Pytorch:小批量过拟合:调试

Pytorch: Overfitting on a small batch: Debugging

我正在构建一个多 class 图像 classifier。
有一个调试技巧可以在单个批次上过度拟合,以检查程序中是否存在更深层次的错误。
如何以一种可以以更便携的格式执行代码的方式设计代码?
一种艰巨且不明智的方法是为小批量构建一个 holdout train/test 文件夹,其中测试 class 由 2 个分布组成 - 已见数据和未见数据,以及模型是否在已见数据上表现更好,并且在看不见的数据上表现不佳,那么我们可以得出结论,我们的网络没有任何更深层次的结构错误。
但是,这似乎不是一种聪明且便携的方式,并且必须解决所有问题。

目前,我有一个数据集 class,我在其中按以下方式对 train/dev/test 中的数据进行分区 -

def split_equal_into_val_test(csv_file=None, stratify_colname='y',
                              frac_train=0.6, frac_val=0.15, frac_test=0.25,
                              ):
    """
    Split a Pandas dataframe into three subsets (train, val, and test).

    Following fractional ratios provided by the user, where val and
    test set have the same number of each classes while train set have
    the remaining number of left classes
    Parameters
    ----------
    csv_file : Input data csv file to be passed
    stratify_colname : str
        The name of the column that will be used for stratification. Usually
        this column would be for the label.
    frac_train : float
    frac_val   : float
    frac_test  : float
        The ratios with which the dataframe will be split into train, val, and
        test data. The values should be expressed as float fractions and should
        sum to 1.0.
    random_state : int, None, or RandomStateInstance
        Value to be passed to train_test_split().

    Returns
    -------
    df_train, df_val, df_test :
        Dataframes containing the three splits.

    """
    df = pd.read_csv(csv_file).iloc[:, 1:]

    if frac_train + frac_val + frac_test != 1.0:
        raise ValueError('fractions %f, %f, %f do not add up to 1.0' %
                         (frac_train, frac_val, frac_test))

    if stratify_colname not in df.columns:
        raise ValueError('%s is not a column in the dataframe' %
                         (stratify_colname))

    df_input = df

    no_of_classes = 4
    sfact = int((0.1*len(df))/no_of_classes)

    # Shuffling the data frame
    df_input = df_input.sample(frac=1)


    df_temp_1 = df_input[df_input['labels'] == 1][:sfact]
    df_temp_2 = df_input[df_input['labels'] == 2][:sfact]
    df_temp_3 = df_input[df_input['labels'] == 3][:sfact]
    df_temp_4 = df_input[df_input['labels'] == 4][:sfact]

    dev_test_df = pd.concat([df_temp_1, df_temp_2, df_temp_3, df_temp_4])
    dev_test_y = dev_test_df['labels']
    # Split the temp dataframe into val and test dataframes.
    df_val, df_test, dev_Y, test_Y = train_test_split(
        dev_test_df, dev_test_y,
        stratify=dev_test_y,
        test_size=0.5,
        )


    df_train = df[~df['img'].isin(dev_test_df['img'])]

    assert len(df_input) == len(df_train) + len(df_val) + len(df_test)

    return df_train, df_val, df_test

def train_val_to_ids(train, val, test, stratify_columns='labels'): # noqa
    """
    Convert the stratified dataset in the form of dictionary : partition['train] and labels.

    To generate the parallel code according to https://stanford.edu/~shervine/blog/pytorch-how-to-generate-data-parallel
    Parameters
    -----------
    csv_file : Input data csv file to be passed
    stratify_columns : The label column

    Returns
    -----------
    partition, labels:
        partition dictionary containing train and validation ids and label dictionary containing ids and their labels # noqa

    """
    train_list, val_list, test_list = train['img'].to_list(), val['img'].to_list(), test['img'].to_list() # noqa
    partition = {"train_set": train_list,
                 "val_set": val_list,
                 }
    labels = dict(zip(train.img, train.labels))
    labels.update(dict(zip(val.img, val.labels)))
    return partition, labels

P.S - 我知道 Pytorch lightning 并且知道它们有一个可以轻松使用的过度拟合功能,但我不想转移到 PyTorch lightning。

我不知道便携性如何,但我使用的一个技巧是修改Dataset中的__len__函数。

如果我修改它来自

def __len__(self):
    return len(self.data_list)

def __len__(self):
    return 20

只会输出数据集中的前20个元素(不考虑shuffle)。您只需更改一行代码,其余的代码应该可以正常工作,所以我认为它非常简洁。