radio icon indicating copy to clipboard operation
radio copied to clipboard

Keras model.fit() integration

Open johnny555 opened this issue 5 years ago • 2 comments

Is it possible to specify a train and validation pipeline in Radio, and then use keras's model.fit() function to run the training loop. This way we can have the benefits of the Radio pipeline with the benefits of keras training loop.

At the moment I can't see a way to do this. It seems that you need to instantiate your model training as part of the Radio pipeline and then run an epoch. If you wanted to check your score against your validation set or perhaps save your model weights, it looks like this needs to be done in your model loop or encoded into your pipeline. So currently it is something like:

train_pipeline = (Pipeline()
                      .init_variable('current_loss')
                      .init_variable('loss_history', init_on_each_run=list)
                          #.init_variable('current_loss', init=float)
                      .init_model('static', ResNoduleNet, 'resnet', config=resnet_config)
                      .predict_model('resnet', x=F(Batch.unpack), save_to=V('predicted'))
                      .train_model(save_to=V('current_loss'), 
                                   name='resnet',
                                   x=F(Batch.unpack),
                                   y=F(Batch.get_labels)
                      )

valid_pipeline = (Pipeline()
                      .init_variable('pred_labels',  init_on_each_run=list)
                      .init_variable('predicted', init_on_each_run=list)
                      .init_variable('true_labels', init_on_each_run=list)
                      .import_model('resnet', train_pipeline)
                      .predict_model('resnet', x= F(Batch.unpack),
                                     save_to=V('predicted'))
                      .call(print_metrics)
                      .run(lazy=True)
                      )
train = (train_dataset+train_pipe)
valid = (valid_dataset+valid_pipe)

for i in range(epochs):
        print(f"epoch {i}")
        t = train.run(epoch=1, batch_size=bs)
        valid.run(epoch=1, batch_size=bs) 

But it would be much nicer if we could just have an interface like.

model = #some keras model
model.fit(train, val_data=valid, epochs=epochs)

johnny555 avatar Sep 06 '18 02:09 johnny555

I can't use: for i in range(epochs): print(f"epoch {i}") t = train.run(epoch=1, batch_size=bs) valid.run(epoch=1, batch_size=bs) to train a model with epochs? even we set a for loop, but the model stile just train a epoch.

and I have tried: train.run(epoch=100, batch_size=bs) but, stil don't work, I need help.

The following is my code: import sys import numpy as np from radio import dataset as ds from radio import CTImagesMaskedBatch as CTIMB from radio.pipelines import combine_crops from radio.models import Keras3DUNet from radio.models.keras.losses import dice_loss from tqdm import tqdm

Todo: Pre data

DIR_CANCER = 'data/cancer/' DIR_NCANCER = 'data/ncancer/' train_time = 1 my_epoch = 20 bs = 4 loss_his = [] cix = ds.FilesIndex(path=DIR_CANCER, dirs=True) ncix = ds.FilesIndex(path=DIR_NCANCER, dirs=True) cancerset = ds.Dataset(index=cix, batch_class=CTIMB) ncancerset = ds.Dataset(index=ncix, batch_class=CTIMB)

print("Len:", len(cancerset), len(ncancerset))

Todo: Build & Trian model

unet_config = dict( input_shape=(1, 32, 64, 64), num_targets=1, loss=dice_loss)

from radio.dataset import F, V

train_unet_pipeline = ( combine_crops(cancerset, ncancerset, batch_sizes=(bs, bs)) .init_variable('loss_acc', 0) .init_variable('current_loss', 0) .init_variable('loss_history', init_on_each_run=list) .init_variable('cancer_len', len(cancerset)) .init_variable('ncancer_len', len(ncancerset)) .init_model( name='3dunet', model_class=Keras3DUNet, config=unet_config, mode='static' ) .train_model( name='3dunet', fetches=[V('loss_acc'), V('cancer_len'), V('ncancer_len')], save_to=V('loss_acc'), x=F(CTIMB.unpack, component='images', data_format='channels_first'), y=F(CTIMB.unpack, component='masks', data_format='channels_first') ) # .run(batch_size=bs, n_epochs=4, drop_last=True, bar=True) .print("loss and acc is:", V('loss_acc')) .update_variable('loss_history', value=V('loss_acc'), mode='a') # Notice: here we use train_on_batch to train our model, train_on_batch return 2 metrics ['loss', 'acc']. )

for i in range(my_epoch): print(f"epoch {i}") t = train_unet_pipeline.run(epoch=1, batch_size=bs)

Raneee avatar Nov 29 '18 01:11 Raneee

@johnny555 can you help me? thanks

Raneee avatar Nov 29 '18 01:11 Raneee