Classes and functions for training and predicting.
   
    
    
    
    
   
class RunHistory:
    '''Class to hold training and prediction run histories'''
    def __init__(self, labels):
        self.train = self.valid = self.test = pd.DataFrame(columns=['loss', *labels])
        self.y_train = self.yhat_train = self.y_valid = self.yhat_valid = self.y_test = self.yhat_test = []
        self.prediction_summary = pd.DataFrame()
- Using 
BCEWithLogitsLossbecause its more numerically stable than using a plain Sigmoid followed by a BCELoss - Also accomodates multi-label classification & class-imbalanced datasets due to the use of 
pos_weights - But this means that the model does not do a final sigmoid at the output layer, since thats done by the loss function
 - So need to do a 
torch.sigmoidon theyhats before using them to calculate accuracy - 2 good discussions on this topic
 
 Note: During the training run, this function will only display auroc scores for the first 4 labels to ensure consistent display. But all scores are recorded in history and will show up in plots.