LeCoda
LeCoda

Reputation: 1016

pytorch - visualization of epoch versus error

I'm trying to learn pytorch, moving over from tensorflow.

Following a tutorial that used this code

import torch
import torch.nn as nn
import numpy as np
import matplotlib as plt
from sklearn import datasets
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split

# 0) Prepare data
bc = datasets.load_breast_cancer()
X, y = bc.data, bc.target

n_samples, n_features = X.shape

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=1234)

# scale
sc = StandardScaler()
X_train = sc.fit_transform(X_train)
X_test = sc.transform(X_test)

X_train = torch.from_numpy(X_train.astype(np.float32))
X_test = torch.from_numpy(X_test.astype(np.float32))
y_train = torch.from_numpy(y_train.astype(np.float32))
y_test = torch.from_numpy(y_test.astype(np.float32))

y_train = y_train.view(y_train.shape[0], 1)
y_test = y_test.view(y_test.shape[0], 1)

# 1) Model
# Linear model f = wx + b , sigmoid at the end
class Model(nn.Module):
    def __init__(self, n_input_features):
        super(Model, self).__init__()
        self.linear = nn.Linear(n_input_features, 1)

    def forward(self, x):
        y_pred = torch.sigmoid(self.linear(x))
        return y_pred

model = Model(n_features)

# 2) Loss and optimizer
num_epochs = 100
learning_rate = 0.01
criterion = nn.BCELoss()
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)

# 3) Training loop
for epoch in range(num_epochs):
    # Forward pass and loss
    y_pred = model(X_train)
    loss = criterion(y_pred, y_train)

    # Backward pass and update
    loss.backward()
    optimizer.step()

    # zero grad before new step
    optimizer.zero_grad()

    if (epoch+1) % 10 == 0:
        print(f'epoch: {epoch+1}, loss = {loss.item():.4f}')


with torch.no_grad():
    y_predicted = model(X_test)
    y_predicted_cls = y_predicted.round()
    acc = y_predicted_cls.eq(y_test).sum() / float(y_test.shape[0])
    print(f'accuracy: {acc.item():.4f}')

Trying to visualize the outputted model, and to visualize how similar the data input to output is, I'm having a bit of problems simply using matploblib,

predicted = model(X_test).detach().numpy()

plt.plot(X_test, y_train, 'ro')
plt.plot(X_test, y_predicted, 'b')
plt.show()

What is a good way to visualize this data? Thanks in advance,

using Ivan's answer - trying to add the train_acc to the function,

train_loss, valid_loss, valid_acc, train_acc = [], [], [],[]
for epoch in range(num_epochs):
    # Forward pass and loss
    y_pred = model(X_train)
    loss = criterion(y_pred, y_train)

    # Backward pass and update
    loss.backward()
    optimizer.step()

    # zero grad before new step
    optimizer.zero_grad()

    train_loss.append(loss.item())
    
#     acc_init = model(X_test).round().eq(y_train).sum() / float(y_train.shape[0])

    train_acc.append(acc_init)
    with torch.no_grad():
        y_pred = model(X_test)
        loss = criterion(y_pred, y_test)
        y_pred_cls = y_pred.round()
        acc = y_pred_cls.eq(y_test).sum() / float(y_test.shape[0])

        valid_loss.append(loss.item())
        valid_acc.append(acc.item())
        
    if (epoch+1) % 10 == 0:
        print(f'epoch: {epoch+1}, loss = {loss.item():.4f}')
        print(f'valid loss: {loss.item():.4f} valid acc: {acc.item():.4f}')

Upvotes: 0

Views: 380

Answers (1)

Ivan
Ivan

Reputation: 40638

Simply collect the losses over epochs, then plot the values. You could compute the validation accuracy and its loss on every epoch, after you've updated the model. Something like:

train_loss, valid_loss, valid_acc = [], [], []
for epoch in range(num_epochs):
    # Forward pass and loss
    y_pred = model(X_train)
    loss = criterion(y_pred, y_train)

    # Backward pass and update
    loss.backward()
    optimizer.step()

    # zero grad before new step
    optimizer.zero_grad()

    train_loss.append(loss.item())

    with torch.no_grad():
        y_pred = model(X_test)
        loss = criterion(y_pred, y_test)
        y_pred_cls = y_pred.round()
        acc = y_pred_cls.eq(y_test).sum() / float(y_test.shape[0])

        valid_loss.append(loss.item())
        valid_acc.append(acc.item())

    if (epoch+1) % 10 == 0:
        print(f'epoch: {epoch+1}, loss = {loss.item():.4f}')
        print(f'valid loss: {loss.item():.4f} valid acc: {acc.item():.4f}')

Then plot with matplotlib or any other library:

plt.plot(train_loss, label='train_loss')
plt.plot(valid_loss, label='valid_loss')
plt.title('loss over epochs')
plt.legend()

enter image description here

Might as well compute the training accuracy!:

plt.plot(train_acc, label='train_acc')
plt.plot(valid_acc, label='valid_acc')
plt.title('accuracy over epochs')
plt.legend()

enter image description here

Upvotes: 1

Related Questions