<jupyter_start><jupyter_text>Define a Model<jupyter_code>class Model(nn.Module):
    
    def __init__(self, input_features=4, h1=8, h2=9, output_features=3):
        super().__init__()
        
        self.f1 = nn.Linear(input_features,h1)    #input layer
        self.f2 = nn.Linear(h1,h2)                # hidden layer
        self.out = nn.Linear(h2, output_features) # output layer
        
    def forward(self, x):
        
        x = nn.functional.relu(self.f1(x))
        x = nn.functional.relu(self.f2(x))
        x = nn.functional.relu(self.out(x))
        
        return x
model = Model() ## instantiate the model
print(model)<jupyter_output>Model(
  (f1): Linear(in_features=4, out_features=8, bias=True)
  (f2): Linear(in_features=8, out_features=9, bias=True)
  (out): Linear(in_features=9, out_features=3, bias=True)
)<jupyter_text>Load Iris data<jupyter_code>df = pd.read_csv('PYTORCH_NOTEBOOKS/Data/iris.csv')

df.head()
### plotting the data set

fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(10,7))
fig.tight_layout()

plots = [(0,1),(2,3),(0,2),(1,3)]
colors = ['b', 'r', 'g']
labels = ['Iris setosa','Iris virginica','Iris versicolor']

for i, ax in enumerate(axes.flat):
    for j in range(3):
        x = df.columns[plots[i][0]]
        y = df.columns[plots[i][1]]
        ax.scatter(df[df['target']==j][x], df[df['target']==j][y], color=colors[j])
        ax.set(xlabel=x, ylabel=y)

fig.legend(labels=labels, loc=3, bbox_to_anchor=(1.0,0.85))
plt.show()
## train test split the dataframe
from sklearn.model_selection import train_test_split

X = df.drop('target',axis=1).values
y = df['target'].values

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

## convert the splitted df to tensors

X_train = torch.FloatTensor(X_train)
X_test = torch.FloatTensor(X_test)
y_train = torch.LongTensor(y_train)
y_test = torch.LongTensor(y_test)
X_train.shape<jupyter_output><empty_output><jupyter_text>Torch Data Loader (for creating batches - not required for small datasets)<jupyter_code>from torch.utils.data import DataLoader, Dataset

trainloader = DataLoader(X_train, batch_size=50, shuffle=True)

testloader = DataLoader(X_test, batch_size=50, shuffle=False)
for b, train in enumerate(trainloader):
    break
train.shape<jupyter_output><empty_output><jupyter_text>Define Loss and Optimizer<jupyter_code>torch.manual_seed(4)
model = Model()
model
loss_function = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.01)<jupyter_output><empty_output><jupyter_text>Train the model<jupyter_code>epochs = 100
losses = []

for i in range(epochs):
    
    i += 1
    
    y_predict = model.forward(X_train) ## predict using the model
    
    loss = loss_function(y_predict, y_train) ## calculate the loss
    
    losses.append(loss)
    
    if i%10==0:
        print(f'Epochs {i} ; Loss : {loss.item()}')
    
    optimizer.zero_grad() ## before update the weights, make it zero to remove remaining derivatives
    
    loss.backward() ## calculate the backward gradient
    
    optimizer.step() ## calculate the loss
### plotting the losses

plt.plot(range(epochs), losses)
plt.title("Loss Graph")
plt.xlabel("Epochs")
plt.ylabel("Loss")
plt.show()<jupyter_output><empty_output><jupyter_text>Validate the model<jupyter_code>with torch.no_grad():
    y_test_val = model.forward(X_test)
    loss = loss_function(y_test_val, y_test)

print(f'loss: {loss:.8f}')
## printing every item of the test data set along with it prediction

correct = 0

with torch.no_grad():
    for i, data in enumerate(X_test):
        y_val = model.forward(data)
        print(f'Row:{i} \t {y_val} \t {y_val.argmax()} \t {y_test[i]}')
        
        if y_val.argmax() == y_test[i]:
            correct += 1

print(f'\n{correct} out of {len(y_test)} = {100*correct/len(y_test):.2f}% correct')<jupyter_output>Row:0 	 tensor([ 3.9359, 11.8165,  6.0317]) 	 1 	 1
Row:1 	 tensor([ 5.1327, 13.2105,  5.5340]) 	 1 	 1
Row:2 	 tensor([15.8134,  9.9174,  0.0000]) 	 0 	 0
Row:3 	 tensor([ 2.7494, 12.7806,  9.0326]) 	 1 	 1
Row:4 	 tensor([ 0.0000, 12.4404, 15.7182]) 	 2 	 2
Row:5 	 tensor([ 0.0000, 12.8935, 22.6560]) 	 2 	 2
Row:6 	 tensor([16.2079, 10.2474,  0.0000]) 	 0 	 0
Row:7 	 tensor([16.8392, 10.4608,  0.0000]) 	 0 	 0
Row:8 	 tensor([ 0.0000, 12.9879, 15.3819]) 	 2 	 2
Row:9 	 tensor([ 0.0000, 13.5616, 18.9501]) 	 2 	 2
Row:10 	 tensor([ 0.0000, 13.4887, 20.2896]) 	 2 	 2
Row:11 	 tensor([15.0628,  9.3498,  0.0000]) 	 0 	 0
Row:12 	 tensor([ 0.0000, 12.8904, 19.1392]) 	 2 	 2
Row:13 	 tensor([ 2.4696, 12.4089,  9.0954]) 	 1 	 1
Row:14 	 tensor([ 0.0000, 13.3409, 15.8235]) 	 2 	 2
Row:15 	 tensor([ 4.8065, 12.7120,  5.5460]) 	 1 	 1
Row:16 	 tensor([ 0.4434, 12.2445, 12.2788]) 	 2 	 2
Row:17 	 tensor([17.1070, 10.6338,  0.0000]) 	 0 	 0
Row:18 	 tensor([ 3.1118, 12.8575,  8.5023]) 	 1 	 1
Row[...]<jupyter_text>Save the model<jupyter_code>torch.save(model.state_dict(),'pytorch_iris_model.pt')<jupyter_output><empty_output><jupyter_text>Load model<jupyter_code>new_model = Model() ### note you need to have the original model definition if your only saving state_dicts

new_model.load_state_dict(torch.load('pytorch_iris_model.pt'))
new_model.eval()
with torch.no_grad():
    y_val = new_model.forward(X_test)
    loss = loss_function(y_val, y_test)
print(f'{loss:.8f}')<jupyter_output>0.06091593<jupyter_text>Applying on a new dataset<jupyter_code>mystery_iris = torch.tensor([5.6,3.7,2.2,0.5])
fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(10,7))
fig.tight_layout()

plots = [(0,1),(2,3),(0,2),(1,3)]
colors = ['b', 'r', 'g']
labels = ['Iris setosa','Iris virginica','Iris versicolor','Mystery iris']

for i, ax in enumerate(axes.flat):
    for j in range(3):
        x = df.columns[plots[i][0]]
        y = df.columns[plots[i][1]]
        ax.scatter(df[df['target']==j][x], df[df['target']==j][y], color=colors[j])
        ax.set(xlabel=x, ylabel=y)
        
    # Add a plot for our mystery iris:
    ax.scatter(mystery_iris[plots[i][0]],mystery_iris[plots[i][1]], color='y')
    
fig.legend(labels=labels, loc=3, bbox_to_anchor=(1.0,0.85))
plt.show()
with torch.no_grad():
    print(new_model(mystery_iris))
    print()
    print(labels[new_model(mystery_iris).argmax()])<jupyter_output>tensor([16.7028, 11.4300,  0.0000])

Iris setosa
{'fraction_non_alphanumeric': 0.16213653603034134, 'fraction_numerical': 0.08075221238938053, 'mean_word_length': 3.936817472698908, 'pattern_counts': {'":': 0, '<': 33, '<?xml version=': 0, '>': 33, 'https://': 0, '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': '9', 'dir': 'jupyter-structured-clean-dedup', 'id': '380372', 'license': 'Apache-2.0', 'n_tokens_mistral': 2932, 'n_tokens_neox': 2539, 'n_words': 504, 'path': 'torch/4. Basic ANN - Iris.ipynb', 'repo_name': 'rishuatgithub/MLPy', 'size': '6328'}