1

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

目前,我有一个数据集类,我在其中以以下方式对 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

PS - 我了解 PyTorch 闪电,并且知道它们具有可以轻松使用的过度拟合功能,但我不想转向 PyTorch 闪电。

4

1 回答 1

1

我不知道它的便携性如何,但我使用的一个技巧是修改__len__.Dataset

如果我从

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

def __len__(self):
    return 20

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

于 2020-10-01T04:59:26.173 回答