<jupyter_start><jupyter_text>Taken from-  https://github.com/krishnaik06/Pytorch-Tutorial/blob/master/Tutorial%204-%20Creating%20ANN%20with%20Pytorch%20On%20Pima%20Diabetes%20Dataset.ipynbwith little changes:- change in architecture (faster convergence)- run a climb hill to monitor model's performance as training progresses<jupyter_code>import torch
import pandas as pd
import torch.nn as nn
import torch.nn.functional as F
import seaborn as  sns
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.metrics import confusion_matrix
from sklearn.metrics import accuracy_score
import matplotlib.pyplot as plt
%matplotlib inline
df = pd.read_csv("diabetes.csv")
df.head()
## Check for Null values
df.isnull().sum()
new_df = df.copy()
new_df["Outcome"] = np.where(new_df['Outcome']==1, "Diabetic", "Not Diabetic")
new_df.head()
## Plot pairwise relationships
# sns.pairplot(new_df, hue="Outcome")
X = df.drop(["Outcome"], axis=1).values  # independent features
y = df["Outcome"].values # dependent features
## Train test data split
X_train, X_test, y_train, y_test = train_test_split(X,y, test_size=0.2, random_state=12)


## Creating tensors
X_train = torch.FloatTensor(X_train)
y_train = torch.FloatTensor(y_train)
X_test = torch.FloatTensor(X_test)
y_test = torch.FloatTensor(y_test)

y_train = y_train.to(dtype=torch.long)
y_test = y_test.to(dtype=torch.long)
df.shape
### Creating ANN Model class with PyTorch

class ANN_Model(nn.Module):
    
    ## Define all the network architecture and variables
    def __init__(self, input_features=8, hidden1=10, hidden2=20, hidden3=10, out_features=2):
        super().__init__()
        ## First fully connected layer
        self.f_connected1 = nn.Linear(input_features, hidden1)
        ## First fully connected layer
        self.f_connected2 = nn.Linear(hidden1, hidden2)
        self.f_connected3 = nn.Linear(hidden2, hidden3)
        ## Output layer
        self.out = nn.Linear(hidden3, out_features)
    
    def forward(self, x):
        ## aplying activation function
        x = F.relu(self.f_connected1(x))
        x = F.relu(self.f_connected2(x))
        x = F.relu(self.f_connected3(x))
        x = self.out(x)
        return x
### Instantiate my ANN module
torch.manual_seed(42)
model = ANN_Model()
## Print the network architecture
model.parameters
## Backward propgation
## -- Define the loss function and define the optimizer

loss_function = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.01)
y_train.dtype
## Ignite the network and let it do the job

epochs = 500
final_losses = []
accuracy = []

for i in range(epochs):
    i += 1
    y_pred = model.forward(X_train)    
    loss = loss_function(y_pred, y_train)
    final_losses.append(loss)
    
    if i%10 == 1:
        print("Epoch no. {} and the loss is: {} ".format(i, loss.item()))
    
    ## Important step: we need to reduce the loss. So after epoch this line 
    # erases the gradient of all the optimized class
    optimizer.zero_grad()
    loss.backward() ## to backpropogate and findout the derivative
    optimizer.step()

    ## Model performance track: run a climbing hill
    predictions = []
    with torch.no_grad():
        for idx, data in enumerate(X_test):
            y_pred = model(data)
            predictions.append(y_pred.argmax().item())
    score = accuracy_score(y_test, predictions)
    accuracy.append(score)


plt.plot(range(epochs), accuracy)
print("Best accuracy: {} for iteration: {}".format(max(accuracy), np.asarray(accuracy).argmax()))
## Plot the loss function
plt.plot(range(epochs), final_losses)
plt.ylabel("Loss")
plt.xlabel("Epoch")
## Pickout the model 
predictions = []
with torch.no_grad():
    for i, data in enumerate(X_test):
        y_pred = model(data)
        predictions.append(y_pred.argmax().item())
print(predictions[:10])
conf_mat = confusion_matrix(y_test, predictions)
sns.heatmap(conf_mat, annot=True)
plt.xlabel("Actual Values")
plt.ylabel("Predicted Values")

## Print accuracy and save the model
score = accuracy_score(y_test, predictions)
torch.save(model, "diabetes.pt")
print("Model accuracy: {}".format(score))<jupyter_output>Model accuracy: 0.7597402597402597
{'fraction_non_alphanumeric': 0.11870845204178537, 'fraction_numerical': 0.019230769230769232, 'mean_word_length': 4.233540372670808, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 4, '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': '1', 'dir': 'jupyter-structured-clean-dedup', 'id': '525204', 'license': 'Apache-2.0', 'n_tokens_mistral': 1447, 'n_tokens_neox': 1384, 'n_words': 349, 'path': 'pytorch/pima_diabetes.ipynb', 'repo_name': 'sangeet2020/ws-20-21', 'size': '4212'}