<jupyter_start><jupyter_text>Mutiple Labels Classification > Predict a color and a marker at the same time.[Credits](https://discuss.pytorch.org/t/a-model-with-multiple-outputs/10440/7)  Imports<jupyter_code>import torch
from torch.utils.data import DataLoader, Dataset
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns
from torch import nn
from torch.nn import functional as F
import torch.optim as optim
import pandas as pd
from collections import Counter<jupyter_output><empty_output><jupyter_text>Data Prep<jupyter_code>data = pd.read_csv('data/train.csv')
data.tail()
data.color.unique()
data.marker.unique()
sns.scatterplot(data=data, hue='color', x='x', y='y')<jupyter_output><empty_output><jupyter_text>Creating Datasets<jupyter_code>class Colors(Dataset):
    def __init__(self,path, transform=None, shuffle=False):
        self.path = path
        self.transform = transform
        self.dataFrame = pd.read_csv(path)
        self.xy = pd.read_csv(path).values
        self.shuffle = shuffle
        
        if self.shuffle:
            np.random.shuffle(self.xy)
            
        self.x = self.xy[:, :2]
        self.color_cate = self.xy [:,-2:-1].reshape(-1)
        self.marker_cate = self.xy[:, -1]
        self.colors_dict = dict([(value, key) for (key, value) in enumerate(['red', 'blue', 'green', 'teal', 'orange', 'purple'])])
        self.marker_dict = dict([(value, key) for (key, value) in enumerate(['^', '+', '*'])])
        self.y_colors = np.array([self.colors_dict[i] for i in self.color_cate])
        self.y_markers = np.array([self.marker_dict[i] for i in self.marker_cate])
        print( self.y_colors, self.y_markers)

        self.len = self.y_colors.shape[0]
        
    def __len__(self):
        return self.len
    
    def __getitem__(self, index):
        sample = self.x[index], self.y_colors[index], self.y_markers[index]
        if self.transform:
            sample = self.transform(sample)
        return sample
    
    def plot(self):
        sns.scatterplot(data=self.dataFrame, x='x', y='y',hue='color')
        plt.show()<jupyter_output><empty_output><jupyter_text>Creating a Transformers<jupyter_code>class ToTensor:
    def __call__(self, samples):
        x, y_colors, y_markers = samples
        return torch.from_numpy(x.astype('float32')) ,torch.from_numpy(np.array(y_colors)).long(),torch.from_numpy(np.array(y_markers)).long()
train = Colors(
    'data/train.csv',
    transform =ToTensor(),
    shuffle=True
)
test = Colors(
    'data/test.csv',
    ToTensor(),
    shuffle=True
)
train[:2]<jupyter_output><empty_output><jupyter_text>LOading the data using the DataLoader<jupyter_code>train_set = DataLoader(dataset=train,
                      batch_size =10,
                      shuffle=True)
test_set = DataLoader(dataset=test,
                      batch_size =10,
                      shuffle=False)<jupyter_output><empty_output><jupyter_text>Creating a Model<jupyter_code>class Net(nn.Module):
    def __init__(self):
        super().__init__()
        # for the color
        self.fc1 = nn.Linear(2, 16)
        self.fc2 = nn.Linear(16, 16)
        self.fc3 = nn.Linear(16, 6)
        # for the marker
        self.fc4 = nn.Linear(2, 16)
        self.fc5 = nn.Linear(16, 16)
        self.fc6 = nn.Linear(16, 1)
    
    def forward(self, x):
        y = x
        # color
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x =  self.fc3(x)
        
        # marker
        y = F.relu(self.fc4(y))
        y = F.relu(self.fc5(y))
        y =  torch.sigmoid(self.fc6(y))
        return x, y
net = Net()
net
criterion1 = torch.nn.CrossEntropyLoss()
criterion2 = torch.nn.BCELoss()
optimizer = torch.optim.Adam(net.parameters(), lr=0.01)
EPOCHS = 5
for epoch in range(EPOCHS):
    for X, y1, y2  in train_set:
        optimizer.zero_grad()
        # forward pass
        out1, out2 = net(X)
        # print(out2, y1, y2, out1)
        loss1 = criterion1(out1, y1)
        loss2 = criterion2(out2, y2.type(torch.FloatTensor).unsqueeze_(1))
        loss = loss1 + loss2
        # backward pass
        loss.backward()
        # update the weights
        optimizer.step()
        
    if (epoch + 1) % 1 == 0:
        print(f'Epoch {epoch+1}/{EPOCHS}')
        print(f"loss: {loss.item():.3f}, accuracy: 0")<jupyter_output>Epoch 1/5
loss: -0.207, accuracy: 0
Epoch 2/5
loss: -11.162, accuracy: 0
Epoch 3/5
loss: -19.537, accuracy: 0
Epoch 4/5
loss: 0.065, accuracy: 0
Epoch 5/5
loss: 0.182, accuracy: 0<jupyter_text>Evaluation<jupyter_code>total_colors = 0
correct_colors = 0
total_markers = 0
correct_markers = 0
with torch.no_grad():
    for data in test_set:
        X, y1, y2 = data
        output1, output2 = net(X)

        output1 = torch.argmax(output1, dim=1)
        output2 = torch.round_(output2.squeeze_(-1))
        for i in range(len(output1)):
            if output1[i] == y1[i]:
                correct_colors +=1
            total_colors +=1
            
        for i in range(len(output2)):
            if output2[i] == y2[i]:
                correct_markers +=1
            total_markers +=1
            
    print(f"Color Accuracy: {correct_colors/total_colors:.3f}, Marker Accuracy: {correct_markers/total_markers:.3f}")<jupyter_output>Color Accuracy: 0.927, Marker Accuracy: 0.818<jupyter_text>Making Predictions<jupyter_code>test.plot()
out1, out2 = net(torch.Tensor([-0.362444, 3.184180]))
out1.argmax(), out2.round()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.13525337222019687, 'fraction_numerical': 0.031170251549398467, 'mean_word_length': 2.73265306122449, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 32, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '8', 'dir': 'jupyter-structured-clean-dedup', 'id': '109298', 'license': 'MIT', 'n_tokens_mistral': 2049, 'n_tokens_neox': 1954, 'n_words': 396, 'path': '05_Experimental/04_Two_Categories_Problem/01_Multi-Label -Classification.ipynb', 'repo_name': 'CrispenGari/pytorch-python', 'size': '5486'}