<jupyter_start><jupyter_text>**modules**<jupyter_code>import csv
import numpy as np
import pandas as pd
import random
import os

import torch
import torchvision
from torch import nn
from torch.autograd import Variable
from torch.utils.data import Dataset, DataLoader, SubsetRandomSampler
from torchvision import transforms
from torchvision.datasets import MNIST
from torchvision.utils import save_image
import torch.nn as nn
import torch.nn.functional as F
from sklearn.metrics import accuracy_score
from sklearn.metrics import confusion_matrix

import time
from matplotlib import pyplot as plt
use_gpu=torch.cuda.is_available()
if use_gpu:
    print("GPU is available!")
else:
    print("Running on CPU!")
random_seed= 100
shuffle_dataset = True
data_path="Dataset_1.csv"
batch_size=10

num_epochs_autoencoder=300
num_epochs_classifier=300
change_error=1e-4
maxloss=1e-3

D_in=828
H1=600
H2=100
H3=50
H4=200
H5=150
H6=50
classes=['Forest','Highway','Insidecity','OpenCountry','Street']<jupyter_output><empty_output><jupyter_text>class for dataset loading<jupyter_code>class Dataset1(Dataset):
    def __init__(self):
        feature=np.asmatrix(pd.read_csv(data_path, header=None, sep = ' ', usecols=[i for i in range(0,828)]))
        label=np.asmatrix(pd.read_csv(data_path, header=None, sep = ' ' , usecols=[828]))
        label=label-1
        self.len=feature.shape[0]
        self.x_data=torch.FloatTensor(feature)
        self.y_data=torch.FloatTensor(label)
        
    def __getitem__(self,index):
        return self.x_data[index],self.y_data[index]
    
    def __len__(self):
         return self.len<jupyter_output><empty_output><jupyter_text>70% for pre training + 20% for classifier training + 10% testing> Indented block<jupyter_code>full_dataset=(pd.read_csv(data_path, header=None, sep = ' ' ,usecols=[i for i in range(0,828)]))
dataset_size = len(full_dataset)
print("dataset has length=",dataset_size)

indices = list(range(dataset_size))

split1 = int(np.floor(0.7 * dataset_size))
split2=int(np.floor(0.9 * dataset_size))

if shuffle_dataset :
#     np.random.seed(100)
    np.random.shuffle(indices)
train_indices1,train_indices2, test_indices = indices[:split1], indices[split1:split2], indices[:split2]


train_sampler1 = SubsetRandomSampler(train_indices1)
train_sampler2 = SubsetRandomSampler(train_indices2)
test_sampler = SubsetRandomSampler(test_indices)
print(np.shape(full_dataset))
dataset=Dataset1()
train_loader1 = torch.utils.data.DataLoader(dataset, batch_size=batch_size, 
                                           sampler=train_sampler1)
train_loader2 = torch.utils.data.DataLoader(dataset, batch_size=batch_size, 
                                           sampler=train_sampler2)
test_loader = torch.utils.data.DataLoader(dataset, batch_size=len(test_indices),
                                                sampler=test_sampler)
dataset<jupyter_output><empty_output><jupyter_text>**class for autoencoder**<jupyter_code>class Autoencoder(nn.Module):
    def __init__(self, D_in, H1,H2):
        super(Autoencoder,self).__init__()
        
        self.encoder1 = torch.nn.Sequential(
            torch.nn.Linear(D_in, H1),
            torch.nn.ReLU(),
            torch.nn.Linear(H1, H2),
        )

        self.decoder1 = torch.nn.Sequential(
            torch.nn.Linear(H2, H1),
            torch.nn.ReLU(),
            torch.nn.Linear(H1, D_in),
        )
        

    def forward(self,x):
        x1 = self.encoder1(x)
        x2 = self.decoder1(x1)
        
        return x1,x2
model=Autoencoder(D_in,H1,H2).cuda()
print(model)
loss_classifier= nn.CrossEntropyLoss()
loss_pretrain = nn.MSELoss()
optimizer = torch.optim.SGD(model.parameters(), lr=0.01 ,momentum=0.9)<jupyter_output>Autoencoder(
  (encoder1): Sequential(
    (0): Linear(in_features=828, out_features=600, bias=True)
    (1): ReLU()
    (2): Linear(in_features=600, out_features=100, bias=True)
  )
  (decoder1): Sequential(
    (0): Linear(in_features=100, out_features=600, bias=True)
    (1): ReLU()
    (2): Linear(in_features=600, out_features=828, bias=True)
  )
)<jupyter_text>training of autoencoder<jupyter_code>##-----check loss sum old
#pre_train:

loss_sum_old=0
for epoch in range(num_epochs_autoencoder):
        loss_sum=0
        model.train()
        for i,data in enumerate(train_loader1,0):
#         print("#MiniBatch=",i)
            inputs,label=data
            print("inputs",inputs)
            print("Labels",label)
            inputs=torch.FloatTensor(inputs)
            label=torch.FloatTensor(label)
            if use_gpu:
                inputs=Variable(inputs).cuda()
                label=Variable(label).cuda()
                label=label.to(device='cuda', dtype=torch.int64)
            else:
                inputs=Variable(inputs).cpu()
                label=Variable(label).cpu()
                label=label.to(device='cpu', dtype=torch.int64)
            label=label.squeeze(1)
    
    # ===================forward=====================
            y_e,y_d = model(inputs)
#             print("y_d",y_d)
#             print("inputs",inputs)
            loss=loss_pretrain(y_d,inputs)
            loss_sum+=loss
    # ===================backward====================
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()
    # ===================log========================
        loss_sum=loss_sum/((dataset_size*0.7)/batch_size)
#         print("loss_sum",loss_sum)
#         print("loss_sum_old",loss_sum_old)
                          
        if((epoch>1 and loss_sum<=0.0002 )):
           print("EPOCHS FOR CONVERGENCE TRAINING LOSS CHANGE<",change_error,"=",epoch)
#          print("TRAIN_SCORE=",score_train)
           break;
        
        if(abs(loss_sum_old-loss_sum)<0.0002):
             ctr=ctr+1
             if(ctr==5):
                 print("EPOCHS AFTER WHICH TRAINING LOSS SHOWS NO CHANGE","=",epoch)
#              print("TEST_LOSS=",loss_te)
                 break; 
  
        else:
                 ctr=0;
           
         
        print('epoch [{}/{}], loss:{:.4f}'.format(epoch+1, num_epochs_autoencoder, loss_sum))
        loss_sum_old=loss_sum
print("finished training autoencoder")<jupyter_output>inputs tensor([[0.3072, 0.1420, 0.8063,  ..., 3.1800, 2.8402, 3.0094],
        [0.2068, 0.6955, 0.5721,  ..., 3.3295, 3.2864, 3.2842],
        [0.5827, 0.6032, 0.3844,  ..., 2.7058, 2.7451, 2.5884],
        ...,
        [0.5882, 0.4233, 0.8391,  ..., 2.9828, 3.5525, 3.3126],
        [0.9044, 0.0573, 0.9881,  ..., 3.6968, 3.4811, 3.1949],
        [0.5854, 0.3886, 0.7276,  ..., 2.1472, 2.5104, 2.4655]])
Labels tensor([[4.],
        [0.],
        [4.],
        [0.],
        [1.],
        [0.],
        [4.],
        [1.],
        [3.],
        [1.]])
inputs tensor([[0.6204, 0.1691, 0.9752,  ..., 3.2655, 3.2799, 3.1752],
        [0.5864, 0.3183, 0.7379,  ..., 3.1646, 3.4055, 2.9354],
        [0.5694, 0.1679, 0.7315,  ..., 1.8587, 2.5601, 2.5891],
        ...,
        [0.5820, 0.3411, 0.8899,  ..., 3.6244, 3.0729, 3.1344],
        [0.2251, 0.1509, 0.9321,  ..., 3.1619, 3.3781, 2.9204],
        [0.6129, 0.2956, 0.9754,  ..., 1.7594, 1.9220, 1.5215]])
Labels tensor([[3.],
        [1.],
       [...]<jupyter_text>modifying the model<jupyter_code># Removing the decoder module from the autoencoder
new_classifier=nn.Sequential(*list(model.children())[:-1])
model=new_classifier
print(model)
#adding linear layer for classification

model.add_module('classifier',nn.Sequential(nn.Linear(H2,50),nn.ReLU(),nn.Linear(50,5)))
print(model)
if use_gpu:
  model=model.cuda()<jupyter_output>Sequential(
  (0): Sequential(
    (0): Linear(in_features=828, out_features=600, bias=True)
    (1): ReLU()
    (2): Linear(in_features=600, out_features=100, bias=True)
  )
  (classifier): Sequential(
    (0): Linear(in_features=100, out_features=50, bias=True)
    (1): ReLU()
    (2): Linear(in_features=50, out_features=5, bias=True)
  )
)<jupyter_text>training of **classifier**<jupyter_code># training the classifier with remaining 20% of train data

loss_sum_old=0
loss_sum=0
ctr=0

for epoch in range(num_epochs_classifier):
  loss_sum=0  
  for i,data in enumerate(train_loader2,0):
    
            inputs,label=data
            #print("inputs",(inputs))
            inputs=torch.FloatTensor(inputs)
            label=torch.FloatTensor(label)
            #print("Label",(label))
            if use_gpu:
                #print("GPU")
                inputs=Variable(inputs).cuda()
                label=Variable(label).cuda()
                label=label.to(device='cuda', dtype=torch.int64)
            else:
                inputs=Variable(inputs).cpu()
                label=Variable(label).cpu()
                label=label.to(device='cpu', dtype=torch.int64)
            label=label.squeeze(1)
    # ===================forward=====================
            output=model(inputs)
            loss=loss_classifier(output,label)
            loss_sum+=loss
            
    # ===================backward====================
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()
    # ===================testing data========================
            for i,data in enumerate(test_loader,0):
                inputs,label=data
                inputs=torch.FloatTensor(inputs)
                label=torch.FloatTensor(label)
                if use_gpu:
                    inputs=Variable(inputs).cuda()
                    label=Variable(label).cuda()
                    label=label.to(device='cuda', dtype=torch.int64)
                else:
                    inputs=Variable(inputs).cpu()
                    label=Variable(label).cpu()
                    label=label.to(device='cpu', dtype=torch.int64)
                label=label.squeeze(1)
    # ===================testing forward=====================
                output=model(inputs)
                output=output.cpu()
#                 loss_te=loss_classifier(output,label)
            
                y_pred = output.detach().numpy()
                label=label.cpu()
                accuracy = accuracy_score(label, np.argmax(y_pred, axis=1))

            loss_sum=loss_sum/((dataset_size*0.2)/batch_size)
#                 loss_sum_old=loss_sum 
            

                  
  if((epoch>1 and loss_sum<0.0002 )):
         print("EPOCHS FOR CONVERGENCE TRAINING LOSS CHANGE<",change_error,"=",epoch)
#        print("TRAIN_SCORE=",score_train)
         break;
        
  if(abs(loss_sum_old-loss_sum)<0.0002):
         ctr=ctr+1
         if(ctr==5):
               print("EPOCHS AFTER WHICH TRAINING LOSS SHOWS NO CHANGE","=",epoch)
#              print("TEST_LOSS=",loss_te)
               break; 
  else:
         ctr=0;
  loss_sum_old=loss_sum 
  print('epoch [{}/{}], Train Error:{:.4f}, Test Accuracy:{:.4f}'.format(epoch+1, num_epochs_classifier, loss_sum, accuracy))  



for i,data in enumerate(train_loader2,0):
                inputs,label=data
                inputs=torch.FloatTensor(inputs)
                label=torch.FloatTensor(label)
                if use_gpu:
                    inputs=Variable(inputs).cuda()
                    label=Variable(label).cuda()
                    label=label.to(device='cuda', dtype=torch.int64)
                else:
                    inputs=Variable(inputs).cpu()
                    label=Variable(label).cpu()
                    label=label.to(device='cpu', dtype=torch.int64)
                label=label.squeeze(1)
    # =================== forward=====================
                output=model(inputs)
                output=output.cpu()
            
                y_pred = output.detach().numpy()
                label=label.cpu()
                accuracy = accuracy_score(label, np.argmax(y_pred, axis=1))
            
            

            
print('epoch [{}/{}], Train Error:{:.4f}, Train Accuracy:{:.4f}'.format(epoch+1, num_epochs_classifier, loss, accuracy))<jupyter_output>epoch [78/300], Train Error:0.0070, Train Accuracy:1.0000<jupyter_text>**performance on test data**<jupyter_code>class_correct=list(0. for i in range(10))
class_total=list(0. for i in range(10))

for i,data in enumerate(test_loader,0):
    
            inputs,label=data
            inputs=torch.FloatTensor(inputs)
            label=torch.FloatTensor(label)
            if use_gpu:
                inputs=Variable(inputs).cuda()
                label=Variable(label).cuda()
                label=label.to(device='cuda', dtype=torch.int64)
            else:
                inputs=Variable(inputs).cpu()
                label=Variable(label).cpu()
                label=label.to(device='cpu', dtype=torch.int64)
            label=label.squeeze(1)
         # ===================forward=====================
            output=model(inputs).cpu()
#             print("output",output)
            output=output.cpu()
            y_pred = output.detach().numpy()
            label=label.cpu()
#             print("label",label)
            pred= np.argmax(y_pred, axis=1)
#             print("pred",len(pred))
            
            for i in range(len(test_indices)):
#               l=label[i]
                if(pred[i]==label[i]):
                     class_correct[label[i]]+=1
                class_total[label[i]]+=1
            print("sum",sum(class_total))
            for i in range(5):
                print('Accuracy of %5s : %f %%' % (classes[i],100*class_correct[i]/float(class_total[i])))
            
#confusion matrix:

output=output.cpu()
y_pred = output.detach().numpy()
label=label.cpu()
accuracy = accuracy_score(label, np.argmax(y_pred, axis=1))
print("test accuracy=",accuracy)
cm=confusion_matrix(label, np.argmax(y_pred, axis=1))
print("Test Confusion_Matrix=",cm)<jupyter_output>test accuracy= 0.6821974965229486
Test Confusion_Matrix= [[214   0  28  32  17]
 [  2 164  28  33   4]
 [ 20  29 153  38  45]
 [ 36  22  20 281  10]
 [  7  27  41  18 169]]<jupyter_text><jupyter_code><jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.15880716273096954, 'fraction_numerical': 0.05200827566526361, 'mean_word_length': 2.429060665362035, 'pattern_counts': {'":': 0, '<': 38, '<?xml version=': 0, '>': 35, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '9', 'dir': 'jupyter-structured-clean-dedup', 'id': '619921', 'license': 'MIT', 'n_tokens_mistral': 5071, 'n_tokens_neox': 4608, 'n_words': 738, 'path': 'Assignement2/task1_autoencoder.ipynb', 'repo_name': 'amritkumar9595/CS7015-Deep-Learning', 'size': '14017'}