| 996 | } |
| 997 | |
| 998 | void ggml_opt_fit( |
| 999 | ggml_backend_sched_t backend_sched, |
| 1000 | ggml_context * ctx_compute, |
| 1001 | ggml_tensor * inputs, |
| 1002 | ggml_tensor * outputs, |
| 1003 | ggml_opt_dataset_t dataset, |
| 1004 | enum ggml_opt_loss_type loss_type, |
| 1005 | enum ggml_opt_optimizer_type optimizer, |
| 1006 | ggml_opt_get_optimizer_params get_opt_pars, |
| 1007 | int64_t nepoch, |
| 1008 | int64_t nbatch_logical, |
| 1009 | float val_split, |
| 1010 | bool silent) { |
| 1011 | ggml_time_init(); |
| 1012 | const int64_t t_start_us = ggml_time_us(); |
| 1013 | |
| 1014 | const int64_t ndata = ggml_opt_dataset_data(dataset)->ne[1]; |
| 1015 | const int64_t nbatch_physical = inputs->ne[1]; |
| 1016 | GGML_ASSERT(ndata % nbatch_logical == 0); |
| 1017 | GGML_ASSERT(nbatch_logical % nbatch_physical == 0); |
| 1018 | |
| 1019 | const int64_t opt_period = nbatch_logical / nbatch_physical; |
| 1020 | const int64_t nbatches_logical = ndata / nbatch_logical; |
| 1021 | |
| 1022 | GGML_ASSERT(val_split >= 0.0f); |
| 1023 | GGML_ASSERT(val_split < 1.0f); |
| 1024 | const int64_t ibatch_split = int64_t(((1.0f - val_split) * nbatches_logical)) * opt_period; // train <-> val split index (physical) |
| 1025 | const int64_t idata_split = ibatch_split * nbatch_physical; |
| 1026 | |
| 1027 | int64_t epoch = 1; |
| 1028 | |
| 1029 | ggml_opt_params params = ggml_opt_default_params(backend_sched, loss_type); |
| 1030 | params.ctx_compute = ctx_compute; |
| 1031 | params.inputs = inputs; |
| 1032 | params.outputs = outputs; |
| 1033 | params.opt_period = opt_period; |
| 1034 | params.get_opt_pars = get_opt_pars; |
| 1035 | params.get_opt_pars_ud = &epoch; |
| 1036 | params.optimizer = optimizer; |
| 1037 | ggml_opt_context_t opt_ctx = ggml_opt_init(params); |
| 1038 | |
| 1039 | // Shuffling the data is generally useful but there is only a point if not all data is used in a single batch. |
| 1040 | if (nbatch_logical < ndata) { |
| 1041 | ggml_opt_dataset_shuffle(opt_ctx, dataset, -1); // Shuffle all data (train + validation). |
| 1042 | } |
| 1043 | |
| 1044 | ggml_opt_result_t result_train = ggml_opt_result_init(); |
| 1045 | ggml_opt_result_t result_val = ggml_opt_result_init(); |
| 1046 | |
| 1047 | ggml_opt_epoch_callback epoch_callback = silent ? nullptr : ggml_opt_epoch_callback_progress_bar; |
| 1048 | |
| 1049 | for (; epoch <= nepoch; ++epoch) { |
| 1050 | if (nbatch_logical < idata_split) { |
| 1051 | ggml_opt_dataset_shuffle(opt_ctx, dataset, idata_split); |
| 1052 | } |
| 1053 | |
| 1054 | ggml_opt_result_reset(result_train); |
| 1055 | ggml_opt_result_reset(result_val); |