Cifar10 resnet how to increase accuracy?

import torch

from PIL import Image

from torch import nn, save, load

from torch.utils.data import DataLoader

import torchvision

from torchvision import datasets

from torchvision.transforms import ToTensor

import torchvision.transforms as transforms

from torchvision import models

if torch.cuda.is_available():
print(“using CUDA”)
device = ‘cuda’
dtype = torch.float32
elif torch.backends.mps.is_available():
print(“using MPS”)
device = ‘mps’
dtype = torch.float32
else:
print(“using CPU”)
device = ‘cpu’
dtype = torch.float32

transform = transforms.Compose([
transforms.Resize(32),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])

])

trainset = torchvision.datasets.CIFAR10(root=‘./data’,train=True, download=True, transform = transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=32, shuffle=True, num_workers=2)

testset = torchvision.datasets.CIFAR10(root=‘./data’,train=False, download=True, transform = transform)
testloader = torch.utils.data.DataLoader(testset, batch_size=32, shuffle=False, num_workers=2)

net = models.resnet50(pretrained=True)
num_ftrs = net.fc.in_features
net.fc = nn.Sequential(
nn.Linear(num_ftrs, 500),
nn.ReLU(),
nn.Linear(500, 300),
nn.Dropout(0.6),
nn.Linear(300,100),
nn.ReLU(),
nn.Dropout(0.5),
nn.Linear(100,50),
nn.ReLU(), # Corrected here
nn.Dropout(0.35),
nn.Linear(50,25),
nn.ReLU(), # Corrected here
nn.Dropout(0.3),
nn.Linear(25,10),
nn.ReLU() # Corrected here
)

print(“Model Info:”)

print(“ResNet50,Pretrained,weight adj. LR=0.01,Mom=0.3,WD=0.0001”)

print(“Schedule step=1,gamma=0.7, 20 epoches”)

Move the model to the GPU

resnet50v2 = net.to(device, dtype=torch.float32)

optimizer = torch.optim.SGD(resnet50v2.parameters(), lr=0.01,momentum=0.3,weight_decay=0.0001)

criterion = nn.CrossEntropyLoss()

scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=5, gamma=0.5)

train_losses =

test_losses =

accuracies =

train_acc =

import matplotlib.pyplot as plt
from tqdm import tqdm

for epoch in range(32): # loop over the dataset multiple times
running_loss = 0.0
correctTrain = 0
totalTrain = 0
pbar = tqdm(enumerate(trainloader, 0), total=len(trainloader), desc=“Epoch {}”.format(epoch+1))
for i, data in pbar:
# get the inputs; data is a list of [inputs, labels]
inputs, labels = data[0].to(device,dtype=torch.float32), data[1].to(device)

    # zero the parameter gradients
    optimizer.zero_grad()

    # forward + backward + optimize
    outputs = resnet50v2(inputs)
    loss = criterion(outputs, labels)
    loss.backward()
    optimizer.step()

    # print statistics
    running_loss += loss.item()
    _, predicted_train = torch.max(outputs.data, 1)
    totalTrain += labels.size(0)
    correctTrain += (predicted_train == labels).sum().item()
    pbar.set_postfix({'loss': running_loss/(i+1)})
train_accuracy = 100 * correctTrain / totalTrain
train_acc.append(train_accuracy)
print(f'Epoch {epoch + 1} loss: {running_loss / len(trainloader):.3f}')

# Start of testing phase
resnet50v2.eval()  # Set the model to evaluation mode
test_loss = 0.0
correct = 0
total = 0
with torch.no_grad():
    for data in testloader:
        images, labels = data[0].to(device,dtype=torch.float32), data[1].to(device)
        outputs = resnet50v2(images)
        loss = criterion(outputs, labels)
        test_loss += loss.item()
        _, predicted = torch.max(outputs.data, 1)
        total += labels.size(0)
        correct += (predicted == labels).sum().item()

print(f'Epoch {epoch + 1} Test loss: {test_loss / len(testloader):.3f}, Accuracy: {100 * correct / total:.2f}%')
#print the learning rate
print(f'Epoch {epoch + 1} Learning rate: {optimizer.param_groups[0]["lr"]}')
train_losses.append(running_loss / len(trainloader))
test_losses.append(test_loss / len(testloader))
accuracies.append(100 * correct / total)

resnet50v2.train() # Set the model back to training model
scheduler.step()

print(‘Finished Training’)

plt.figure(figsize=(10, 5))
plt.plot(train_losses, label=‘Training Loss’)
plt.plot(test_losses, label=‘Test Loss’)
plt.xlabel(‘Epochs’)
plt.ylabel(‘Loss’)
plt.legend()
plt.show()

plt.figure(figsize=(10, 5))
plt.plot(accuracies, label=‘Accuracy’)
plt.plot(train_acc, label=‘Training Accuracy’)
plt.xlabel(‘Epochs’)
plt.ylabel(‘Accuracy (%)’)
plt.legend()
plt.show()

print(“Model Info:”)
print(“ResNet50,Pretrained,weight adj. LR=0.01,Mom=0.3,WD=0.0001”)
print(“Schedule step=1,gamma=0.7, 20 epoches”)

This is a the Resnet Model you can try to fine tune and edit with :smiley:

import torch
import torch.nn as nn

class BasicBlock(nn.Module):
    expansion = 1

    def __init__(self, in_channels, out_channels, stride=1, downsample=None):
        super(BasicBlock, self).__init__()
        self.conv1 = nn.Conv2d(in_channels, out_channels, kernel_size=3, stride=stride, padding=1, bias=False)
        self.bn1 = nn.BatchNorm2d(out_channels)

        self.relu = nn.ReLU(inplace=True)

        self.conv2 = nn.Conv2d(out_channels, out_channels, kernel_size=3, stride=1, padding=1, bias=False)
        self.bn2 = nn.BatchNorm2d(out_channels)

        self.downsample = downsample
        self.stride = stride

    def forward(self, x):
        identity = x

        out = self.conv1(x)
        out = self.bn1(out)
        out = self.relu(out)

        out = self.conv2(out)
        out = self.bn2(out)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
        if self.downsample is not None:
            identity = self.downsample(x)

        out += identity
        out = self.relu(out)

        return out
    

class Bottleneck(nn.Module):
    expansion = 4

    def __init__(self, in_channels, out_channels, stride=1, downsample=None):
        super(Bottleneck, self).__init__()
        self.conv1 = nn.Conv2d(in_channels, out_channels, kernel_size=1, bias=False)
        self.bn1 = nn.BatchNorm2d(out_channels)

        self.conv2 = nn.Conv2d(out_channels, out_channels, kernel_size=3, stride=stride, padding=1, bias=False)
        self.bn2 = nn.BatchNorm2d(out_channels)

        self.conv3 = nn.Conv2d(out_channels, out_channels * self.expansion, kernel_size=1, bias=False)
        self.bn3 = nn.BatchNorm2d(out_channels * self.expansion)

        self.relu = nn.ReLU(inplace=True)
        self.downsample = downsample
        self.stride = stride

    def forward(self, x):
        identity = x

        out = self.conv1(x)
        out = self.bn1(out)
        out = self.relu(out)

        out = self.conv2(out)
        out = self.bn2(out)
        out = self.relu(out)

        out = self.conv3(out)
        out = self.bn3(out)

        if self.downsample is not None:
            identity = self.downsample(x)

        out += identity
        out = self.relu(out)

        return out



class ResNet(nn.Module):
    def __init__(self, block, layers, num_classes=1000):
        super(ResNet, self).__init__()
        self.in_channels = 64
        self.conv1 = nn.Conv2d(3, self.in_channels, kernel_size=7, stride=2, padding=3, bias=False)
        self.bn1 = nn.BatchNorm2d(self.in_channels)
        self.relu = nn.ReLU(inplace=True)
        self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)


        self.layer1 = self._make_layer(block, 64, layers[0])
        self.layer2 = self._make_layer(block, 128, layers[1], stride=2)
        self.layer3 = self._make_layer(block, 256, layers[2], stride=2)
        self.layer4 = self._make_layer(block, 512, layers[3], stride=2)
        
        self.avgpool = nn.AdaptiveAvgPool2d((1, 1))
        self.fc = nn.Linear(512 * block.expansion, num_classes)

    def _make_layer(self, block, out_channels, blocks, stride=1):
        downsample = None

        if stride != 1 or self.in_channels != out_channels * block.expansion:
            downsample = nn.Sequential(
                nn.Conv2d(self.in_channels, out_channels * block.expansion, kernel_size=1, stride=stride, bias=False),
                nn.BatchNorm2d(out_channels * block.expansion),
            )

        layers = []
        layers.append(block(self.in_channels, out_channels, stride, downsample))
        self.in_channels = out_channels * block.expansion
        for _ in range(1, blocks):
            layers.append(block(self.in_channels, out_channels))

        return nn.Sequential(*layers)

    def forward(self, x):
        x = self.conv1(x)
        x = self.bn1(x)
        x = self.relu(x)
        
        x = self.maxpool(x)

        x = self.layer1(x)
        x = self.layer2(x)
        x = self.layer3(x)
        x = self.layer4(x)

        x = self.avgpool(x)
        x = torch.flatten(x, 1)
        x = self.fc(x)

        return x

Hi isaac, below is the model and code that I used I achieved 86% ACC, hope this helps!

import torch
import torchvision
import torchvision.transforms as transforms
from tqdm import tqdm
from torch import nn
import matplotlib.pyplot as plt

#include to ensure fallback to other accerleration methods
if torch.cuda.is_available():
    print("using CUDA")
    device = 'cuda'
    dtype = torch.float32
elif torch.backends.mps.is_available():
    print("using MPS")
    device = 'mps'
    dtype = torch.float32
else:
    print("using CPU")
    device = 'cpu'
    dtype = torch.float32
transformRes = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
])

trainsetRes = torchvision.datasets.CIFAR10(root='./data', train=True, download=True, transform=transformRes)
trainloaderRes16 = torch.utils.data.DataLoader(trainsetRes, batch_size=16, shuffle=True, num_workers=10)

testsetRes = torchvision.datasets.CIFAR10(root='./data', train=False, download=True, transform=transformRes)
testloaderRes16 = torch.utils.data.DataLoader(testsetRes, batch_size=16, shuffle=False, num_workers=10)
import torchvision.models as models

# Load the pretrained model from pytorch
resnet50v2 = models.resnet50(pretrained=True)

# Freeze the parameters of the model
for param in resnet50v2.parameters():
    param.requires_grad = True


# Change the final layer to match the number of classes in the CIFAR-10 dataset
num_ftrs = resnet50v2.fc.in_features
resnet50v2.fc = nn.Sequential(
    nn.Linear(num_ftrs, 500),
    nn.ReLU(),
    nn.Linear(500, 200),
    nn.Dropout(0.5),
    nn.Linear(200,40),
    nn.ReLU(),
    nn.Dropout(0.3),
    nn.Linear(40,10),
    nn.ReLU()

)
print("Model Info:")
print("ResNet50,Pretrained,weight adj. LR=0.01,Mom=0.3,WD=0.0001")
print("Schedule step=1,gamma=0.7, 20 epoches")

# Move the model to the GPU
resnet50v2 = resnet50v2.to(device, dtype=torch.float32)


optimizer = torch.optim.SGD(resnet50v2.parameters(), lr=0.01,momentum=0.3,weight_decay=0.0001)
criterion = nn.CrossEntropyLoss()
scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=5, gamma=0.5)
train_losses = []
test_losses = []
accuracies = []
train_acc = []

for epoch in range(20):  # loop over the dataset multiple times
    running_loss = 0.0
    correctTrain = 0
    totalTrain = 0
    pbar = tqdm(enumerate(trainloaderRes16, 0), total=len(trainloaderRes16), desc="Epoch {}".format(epoch+1))
    for i, data in pbar:
        # get the inputs; data is a list of [inputs, labels]
        inputs, labels = data[0].to(device,dtype=torch.float32), data[1].to(device)

        # zero the parameter gradients
        optimizer.zero_grad()

        # forward + backward + optimize
        outputs = resnet50v2(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()

        # print statistics
        running_loss += loss.item()
        _, predicted_train = torch.max(outputs.data, 1)
        totalTrain += labels.size(0)
        correctTrain += (predicted_train == labels).sum().item()
        pbar.set_postfix({'loss': running_loss/(i+1)})
    train_accuracy = 100 * correctTrain / totalTrain
    train_acc.append(train_accuracy)
    print(f'Epoch {epoch + 1} loss: {running_loss / len(trainloaderRes16):.3f}')

    # Start of testing phase
    resnet50v2.eval()  # Set the model to evaluation mode
    test_loss = 0.0
    correct = 0
    total = 0
    with torch.no_grad():
        for data in testloaderRes16:
            images, labels = data[0].to(device,dtype=torch.float32), data[1].to(device)
            outputs = resnet50v2(images)
            loss = criterion(outputs, labels)
            test_loss += loss.item()
            _, predicted = torch.max(outputs.data, 1)
            total += labels.size(0)
            correct += (predicted == labels).sum().item()

    print(f'Epoch {epoch + 1} Test loss: {test_loss / len(testloaderRes16):.3f}, Accuracy: {100 * correct / total:.2f}%')
    #print the learning rate
    print(f'Epoch {epoch + 1} Learning rate: {optimizer.param_groups[0]["lr"]}')
    train_losses.append(running_loss / len(trainloaderRes16))
    test_losses.append(test_loss / len(testloaderRes16))
    accuracies.append(100 * correct / total)

    resnet50v2.train() # Set the model back to training model
    scheduler.step()



print('Finished Training')

plt.figure(figsize=(10, 5))
plt.plot(train_losses, label='Training Loss')
plt.plot(test_losses, label='Test Loss')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()
plt.show()

plt.figure(figsize=(10, 5))
plt.plot(accuracies, label='Accuracy')
plt.plot(train_acc, label='Training Accuracy')
plt.xlabel('Epochs')
plt.ylabel('Accuracy (%)')
plt.legend()
plt.show()

Hi , thanks for the help! How about this?
import pandas as pd
import numpy as np
import torch
from torch.nn.utils.rnn import pad_sequence
from torchtext.vocab import build_vocab_from_iterator
data = pd.read_csv(‘emotion_sentimen_dataset.csv’)

import torch
if torch.backends.mps.is_available():
mps_device = torch.device(“mps”)
x = torch.ones(1, device=mps_device)
print (x)
else:
print (“MPS device not found.”)

data = data.drop(‘Unnamed: 0’, axis=1)

data.head()

get unique values of emotion

data[‘Emotion’].unique()

sentences = data[‘text’].tolist()

emotion_mapping = {emotion: i for i, emotion in enumerate(data[‘Emotion’].unique())}
data[‘Emotions’] = data[‘Emotion’].map(emotion_mapping)
labels = data[‘Emotions’].tolist()

Tokenization and vocabulary building

tokenize = lambda x: x.split()
def yield_tokens(data):
for text in data:
yield tokenize(text)

vocab = build_vocab_from_iterator(yield_tokens(sentences), specials=[“”, “”])
vocab.set_default_index(vocab[“”])

Tokenizing and creating padded sequences

text_pipeline = lambda x: [vocab[token] for token in tokenize(x)]
vectorized_seqs = [torch.tensor(text_pipeline(sentence)) for sentence in sentences]
padded_sequences = pad_sequence(vectorized_seqs, batch_first=True, padding_value=vocab[‘’])
labels_tensor = torch.tensor(labels, dtype=torch.long)

from sklearn.model_selection import train_test_split

Split data into training and validation sets

import torch.nn as nn
import torch.nn.functional as F

class TextCNN(nn.Module):
def init(self, vocab_size, embed_dim, num_filters, filter_sizes, num_classes):
super(TextCNN, self).init()
self.embedding = nn.Embedding(vocab_size, embed_dim)
self.convs = nn.ModuleList(
[nn.Conv1d(in_channels=embed_dim, out_channels=num_filters, kernel_size=fs) for fs in filter_sizes]
)
self.dropout = nn.Dropout(0.5)
self.pool = nn.MaxPool1d(kernel_size=2) # Max pooling layer
self.fc = nn.Linear(num_filters * len(filter_sizes) // 2, num_classes) # Adjusted for max pooling

def forward(self, x):
    x = self.embedding(x)
    x = x.permute(0, 2, 1)
    x = [F.relu(conv(x)).max(dim=2)[0] for conv in self.convs]
    x = torch.cat(x, 1)
    x = self.pool(x)  # Apply max pooling
    x = self.dropout(x)
    x = self.fc(x)
    return F.log_softmax(x, dim=1)  # Using log_softmax for numerical stability

Hyperparameters

vocab_size = len(vocab)
embed_dim = 16
num_filters = 100 # Changed to 100 as per your text
filter_sizes = [3, 4, 5] # Changed to [3, 4, 5] as per your text
num_classes = 13

model = TextCNN(vocab_size, embed_dim, num_filters, filter_sizes, num_classes).to(mps_device)
print(model)

Define loss function and optimizer

criterion = nn.NLLLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)

from torch.utils.data import DataLoader, TensorDataset
from tqdm import tqdm

train_sequences, val_sequences, train_labels, val_labels = train_test_split(padded_sequences, labels_tensor, test_size=0.2, random_state=42)
batch_size = 32

Create data loaders

Create data loaders

train_data = TensorDataset(train_sequences.to(mps_device), train_labels.to(mps_device))
train_loader = DataLoader(train_data, batch_size=batch_size, shuffle=True)

val_data = TensorDataset(val_sequences.to(mps_device), val_labels.to(mps_device))
val_loader = DataLoader(val_data, batch_size=batch_size, shuffle=False)

Training loop

for epoch in range(2):
# Training phase
model.train()
train_loss = 0.0
train_correct = 0
for sequences, labels in train_loader:
optimizer.zero_grad()
outputs = model(sequences).squeeze()
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
_, predicted = torch.max(outputs, 1)
train_correct += (predicted == labels).sum().item()
train_loss += loss.item()
train_accuracy = train_correct / len(train_loader.dataset)

Validation phase

val_loss = 0.0
val_correct = 0
with torch.no_grad():
for sequences, labels in val_loader:
val_outputs = model(sequences).squeeze()
loss = criterion(val_outputs, labels)
_, val_predicted = torch.max(val_outputs, 1)
val_correct += (val_predicted == labels).sum().item()
val_loss += loss.item()
val_accuracy = val_correct / len(val_loader.dataset)

print(f’Epoch {epoch+1}, Loss: {train_loss / len(train_loader)}, Accuracy: {train_accuracy}, Val Loss: {val_loss / len(val_loader)}, Val Accuracy: {val_accuracy}')

Prediction with class output

test_sentences = [“Why did you have to do this you incompetent little shit!”, “I love you so much that i want to love you even more”, “Dont make me worried so much please”, “What a relief”, “Lets do something fun and exciting!”]
test_seqs = [torch.tensor(text_pipeline(sentence)) for sentence in test_sentences]
test_padded = pad_sequence(test_seqs, batch_first=True, padding_value=vocab[‘’]).to(mps_device)

with torch.no_grad():
predictions = model(test_padded)
class_predictions = torch.argmax(predictions, dim=1)

print(class_predictions)  # Outputs emotions directly

{‘hate’: 0, ‘neutral’: 1, ‘anger’: 2, ‘love’: 3, ‘worry’: 4, ‘relief’: 5, ‘happiness’: 6, ‘fun’: 7, ‘empty’: 8, ‘enthusiasm’: 9, ‘sadness’: 10, ‘surprise’: 11, ‘boredom’: 12}