Saltar al contenido

Validación cruzada para el conjunto de datos MNIST con pytorch y sklearn

Posterior a consultar especialistas en el tema, programadores de diversas ramas y maestros hemos dado con la respuesta al dilema y la dejamos plasmada en esta publicación.

Solución:

¡Creo que estás confundido!

Ignore la segunda dimensión por un tiempo. Cuando tiene 45000 puntos y usa una validación cruzada de 10 pliegues, ¿cuál es el tamaño de cada pliegue? 45000/10 es decir 4500.

Significa que cada uno de sus pliegues contendrá 4500 puntos de datos, y uno de esos pliegues se utilizará para pruebas y el resto para entrenamiento, es decir

Para las pruebas: un pliegue => 4500 puntos de datos => tamaño: 4500
Para entrenamiento: pliegues restantes => 45000-4500 puntos de datos => tamaño: 45000-4500=40500

Por lo tanto, para la primera iteración, los primeros 4500 puntos de datos (correspondiente a índices) se utilizará para pruebas y el resto para entrenamiento. (Consulte la imagen de abajo)

Dado que sus datos son x_train: torch.Size([45000, 784]) y y_train: torch.Size([45000])así es como debería verse su código:

for train_index, test_index in kfold.split(x_train, y_train):  
    print(train_index, test_index)

    x_train_fold = x_train[train_index] 
    y_train_fold = y_train[train_index] 
    x_test_fold = x_train[test_index] 
    y_test_fold = y_train[test_index] 

    print(x_train_fold.shape, y_train_fold.shape) 
    print(x_test_fold.shape, y_test_fold.shape) 
    break 

[ 4500  4501  4502 ... 44997 44998 44999] [   0    1    2 ... 4497 4498 4499]
torch.Size([40500, 784]) torch.Size([40500])
torch.Size([4500, 784]) torch.Size([4500])

Entonces, cuando dices

quiero la variable x_train_fold para ser la primera imagen 4500 … antorcha de forma. Tamaño ([4500, 784]).

te equivocas. este tamaño corresponde a x_test_fold. En la primera iteración, basada en 10 pliegues, x_train_fold tendrá 40500 puntos, por lo que se supone que su tamaño es torch.Size([40500, 784]).

Imagen de validación de plegado en K

Creo que lo tengo ahora mismo, pero siento que el código está un poco desordenado, con 3 bucles anidados. ¿Hay alguna forma más simple de hacerlo o está bien este enfoque?

Aquí está mi código para el entrenamiento con validación cruzada:

def train(network, epochs, save_Model = False):
    total_acc = 0
    for fold, (train_index, test_index) in enumerate(kfold.split(x_train, y_train)):
        ### Dividing data into folds
        x_train_fold = x_train[train_index]
        x_test_fold = x_train[test_index]
        y_train_fold = y_train[train_index]
        y_test_fold = y_train[test_index]

        train = torch.utils.data.TensorDataset(x_train_fold, y_train_fold)
        test = torch.utils.data.TensorDataset(x_test_fold, y_test_fold)
        train_loader = torch.utils.data.DataLoader(train, batch_size = batch_size, shuffle = False)
        test_loader = torch.utils.data.DataLoader(test, batch_size = batch_size, shuffle = False)

        for epoch in range(epochs):
            print('nEpoch  /  nFold number  / '.format(epoch + 1, epochs, fold + 1 , kfold.get_n_splits()))
            correct = 0
            network.train()
            for batch_index, (x_batch, y_batch) in enumerate(train_loader):
                optimizer.zero_grad()
                out = network(x_batch)
                loss = loss_f(out, y_batch)
                loss.backward()
                optimizer.step()
                pred = torch.max(out.data, dim=1)[1]
                correct += (pred == y_batch).sum()
                if (batch_index + 1) % 32 == 0:
                    print('[/ (:.0f%)]tLoss: :.6ft Accuracy::.3f%'.format(
                        (batch_index + 1)*len(x_batch), len(train_loader.dataset),
                        100.*batch_index / len(train_loader), loss.data, float(correct*100) / float(batch_size*(batch_index+1))))
        total_acc += float(correct*100) / float(batch_size*(batch_index+1))
    total_acc = (total_acc / kfold.get_n_splits())
    print('nnTotal accuracy cross validation: :.3f%'.format(total_acc))

Te metiste con los índices.

x_train = x[train_index]
x_test = x[test_index]
y_train = y[train_index]
y_test = y[test_index]
    x_fold = x_train[train_index]
    y_fold = y_train[test_index]

Debería ser:

x_fold = x_train[train_index]
y_fold = y_train[train_index]

Recuerda que tienes el privilegio esclarecer si te fue útil.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *