简体   繁体   中英

include early stopping in C

I want to stop the for loop for validation set when the current accuracy is less than previous accuracy calculated in the loop.

for (int j = 0; j < epochs; j++) {
    DPRINT("Epoch %d: 000%%", j + 1);
    DTIME_START_COUNTER;
    for (int i = 0; i < train_data->m; i++) {
        X->data[0] = train_data->data[i];
        y->data[0] = train_labels->data[i];
        
        backprop(network, X, y);
        
        if (i % (int)mini_batch_size == 0 || i == train_data->m - 1) {
            DPRINT("\b\b\b\b%03.0f%%", i * 100 / (double)(train_data->m - 1));
            apply_derivation(network, mini_batch_size, training_rate);
        }
    }
    DPRINT("  Eval accuracy: %.2f%%\n",
    network_accuracy(network, eval_data, eval_labels, NULL));
}

Yes break, but I want to store accuracy (from network_accuracy) in array and compare the value of two consecutive iterations

You need to do something twice, or just finer control, do an extract method refactoring and put the code in a function. Then call that function.

// Put allocation of structs into their own function.
// All the necessary allocation goes in here.
Network *Network_new() {
    // If you simply did `Network network` it would be automatically
    // freed when the function exits. To return a complex value,
    // allocate it on the heap.
    return malloc(sizeof(Network);
}

// Pass in everything it needs. No globals.
// I'm just guessing at the types.
// A proliferation of arguments might suggest the need for a struct
// to gather them together.
Network *do_the_thing(
  Data *train_data,
  Data *train_labels,
  Data *x, Data *y,
  size_t mini_batch_size,
  int training_rate
) {
    // Allocate a new Network struct.
    Network *network = Network_new();
    
    for (int i = 0; i < train_data->m; i++) {
        x->data[0] = train_data->data[i];
        y->data[0] = train_labels->data[i];
        
        backprop(network, x, y);
        
        if (i % (int)mini_batch_size == 0 || i == train_data->m - 1) {
            DPRINT("\b\b\b\b%03.0f%%", i * 100 / (double)(train_data->m - 1));
            apply_derivation(network, mini_batch_size, training_rate);
        }
    }
    
    // Presumably backprop and apply_derivation have changed network.
    return network;
}

// Allocate space for two Network pointers.
Network *networks[2];

for(int i = 0; i < 2; i++) {
  // Save the results to the array.
  networks[i] = do_the_thing(
    train_data,
    train_labels,
    x, y,
    mini_batch_size,
    training_rate
  );
}

// Compare networks[0] and networks[1] as you like.

// Then free them.
for(int i = 0; i < 2; i++) {
  free(network[i]);
}

Alternatively, pass in a pre-allocated return value. This is more flexible, but requires a bit more work in the code calling the function.

Network *do_the_thing(
  Data *train_data,
  Data *train_labels,
  Data *x, Data *y,
  size_t mini_batch_size,
  int training_rate,
  Network *network
) {
  // same as before, but don't allocate the network
}

// Allocate space for two Networks.
// Again, there may be additional allocation and initialization required.
Network networks[2];

for(int i = 0; i < 2; i++) {
  do_the_thing(
    train_data,
    train_labels,
    x, y,
    mini_batch_size,
    training_rate,
    &network[i]  // pass in the pre-allocated memory
  );
}

// No need to free, it will be done automatically.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM