Traceback (most recent call last):
File "D:\TWSAPI\source\pythonclient\tws_env\Code\PyTorch_Vision.py", line 308, in
train_step(model=model_2,
File "D:\TWSAPI\source\pythonclient\tws_env\Code\PyTorch_Vision.py", line 158, in train_step
y_pred = model(X)
^^^^^^^^
File "D:\TWSAPI\source\pythonclient.venv\Lib\site-packages\torch\nn\modules\module.py", line 1511, in _wrapped_call_impl
return self._call_impl(*args, *kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\TWSAPI\source\pythonclient.venv\Lib\site-packages\torch\nn\modules\module.py", line 1520, in _call_impl
return forward_call(args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\TWSAPI\source\pythonclient\tws_env\Code\PyTorch_Vision.py", line 115, in forward
x - self.classifier(x)
^~~~~~
RuntimeError: The size of tensor a (7) must match the size of tensor b (10) at non-singleton dimension 3
I am assuming the main error is:
RuntimeError: The size of tensor a (7) must match the size of tensor b (10) at non-singleton dimension 3
and its within the FashionMNISTModelV2 class (self.classifier)
Code:
import torch
from torch import nn
import torchvision
from torchvision import datasets
from torchvision import transforms
from torchvision.transforms import ToTensor
from torch.utils.data import DataLoader
from timeit import default_timer as timer
import matplotlib.pyplot as plt
import argparse
from tqdm.auto import tqdm
from pathlib import Path
if Path("helper_functions.py").is_file():
print("helper_functions.py already exists")
else:
print("downloading helper_functions")
request = requests.get("https://raw.githubusercontent.com/mrdbourke/pytorch-deep-learning/main/helper_functions.py")
with open("helper_functions.py", "wb") as f:
f.write(request.content)
from helper_functions import plot_predictions, plot_decision_boundary,accuracy_fn
parser = argparse.ArgumentParser(description='CPU/GPU')
parser.add_argument('--disable-cuda', action='store_true', help='Disable CUDA')
args = parser.parse_args()
args.device = None
if not args.disable_cuda and torch.cuda.is_available():
args.device = torch.device('cuda')
else:
args.device = torch.device('cpu')
class FashionMNISTModelV0(nn.Module):
def __init__(self,
input_shape: int,
hidden_units: int,
output_shape: int):
super().__init__()
self.layer_stack = nn.Sequential(
nn.Flatten(),
nn.Linear(in_features=input_shape,
out_features=hidden_units),
nn.Linear(in_features=hidden_units,
out_features=output_shape),
)
def forward(self, x):
return self.layer_stack(x)
class FashionMNISTModelV1(nn.Module):
def __init__(self,
input_shape: int,
hidden_units: int,
output_shape: int):
super().__init__()
self.layer_stack = nn.Sequential(
nn.Flatten(),
nn.Linear(in_features=input_shape,
out_features=hidden_units),
nn.ReLU(),
nn.Linear(in_features=hidden_units,
out_features=output_shape),
nn.ReLU(),
)
def forward(self, x):
return self.layer_stack(x)
class FashionMNISTModelV2(nn.Module):
def __init__(self, input_shape: int, hidden_units: int, output_shape: int):
super().__init__()
self.conv_block_1 = nn.Sequential(
nn.Conv2d(in_channels=input_shape,
out_channels=hidden_units,
kernel_size=3,
stride=1,
padding=1),
nn.ReLU(),
nn.Conv2d(in_channels=hidden_units,
out_channels=hidden_units,
kernel_size=3,
stride=1,
padding=1),
nn.ReLU(),
nn.MaxPool2d(kernel_size=2,
stride=2)
)
self.conv_block_2 = nn.Sequential(
nn.Conv2d(in_channels=hidden_units,
out_channels=hidden_units,
kernel_size=3,
stride=1,
padding=1),
nn.ReLU(),
nn.Conv2d(in_channels=hidden_units,
out_channels=hidden_units,
kernel_size=3,
stride=1,
padding=1),
nn.ReLU(),
nn.MaxPool2d(kernel_size=2)
)
self.classifier = nn.Sequential(
nn.Flatten(),
nn.Linear(in_features=10*7*7,
out_features=output_shape)
)
def forward(self, x):
print(f"pre conv 1 {x.shape}")
x = self.conv_block_1(x)
print(f"conv 1 {x.shape}")
x = self.conv_block_2(x)
print(f"conv 2 {x.shape}")
x - self.classifier(x)
print(x.shape)
return x
def print_train_time(start: float,
end: float,
device: torch.device = None):
total_time = end - start
print(f'Training time on {device}: {total_time:.3f} seconds')
return total_time
def eval_model(model: torch.nn.Module,
data_loader: torch.utils.data.DataLoader,
loss_fn: torch.nn.Module,
accuracy_fn,
device=args.device):
loss, acc = 0,0
model.eval()
with torch.inference_mode():
for X, y in tqdm(data_loader):
X,y = X.to(device), y.to(device)
y_pred = model(X)
loss += loss_fn(y_pred, y)
acc += accuracy_fn(y_true=y,
y_pred=y_pred.argmax(dim=1))
loss = loss / len(data_loader)
acc = acc / len(data_loader)
return {"model_name": model.__class__.__name__,
"model_loss": loss.item(),
"model_acc": acc}
def train_step(model: torch.nn.Module,
data_loader: torch.utils.data.DataLoader,
loss_fn: torch.nn.Module,
optimizer: torch.optim.Optimizer,
accuracy_fn,
device: torch.device = args.device):
train_loss, train_acc = 0, 0
for batch, (X, y) in enumerate(data_loader):
# Send data to GPU
X, y = X.to(device), y.to(device)
# 1. Forward pass
y_pred = model(X)
# 2. Calculate loss
loss = loss_fn(y_pred, y)
train_loss += loss
train_acc += accuracy_fn(y_true=y,
y_pred=y_pred.argmax(dim=1)) # Go from logits -> pred labels
# 3. Optimizer zero grad
optimizer.zero_grad()
# 4. Loss backward
loss.backward()
# 5. Optimizer step
optimizer.step()
# Calculate loss and accuracy per epoch and print out what's happening
train_loss /= len(data_loader)
train_acc /= len(data_loader)
print(f"Train loss: {train_loss:.5f} | Train accuracy: {train_acc:.2f}%")
def test_step(model: torch.nn.Module,
data_loader: torch.utils.data.DataLoader,
loss_fn: torch.nn.Module,
accuracy_fn,
device: torch.device = args.device):
test_loss,test_acc = 0, 0
model.eval()
with torch.inference_mode():
for X, y in test_dataloader:
X, y = X.to(device), y.to(device)
test_pred = model(X)
test_loss += loss_fn(test_pred, y)
test_acc += accuracy_fn(y_true=y, y_pred=test_pred.argmax(dim=1))
test_loss /= len(data_loader)
test_acc /= len(data_loader)
print(f"Test Loss: {test_loss:.5f} | Test Accuracy: {test_acc:.5f}%\n")
torch.manual_seed(42)
train_data = datasets.FashionMNIST('../data',
train=True,
download=True,
transform=torchvision.transforms.ToTensor(),
target_transform=None)
test_data = datasets.FashionMNIST('../data',
train=False,
download=True,
transform=torchvision.transforms.ToTensor(),
target_transform=None)
BATCH_SIZE = 32
train_dataloader = DataLoader(dataset=train_data,
batch_size=BATCH_SIZE,
shuffle=True)
test_dataloader = DataLoader(dataset=test_data,
batch_size=BATCH_SIZE,
shuffle=False)
image, label = train_data[0]
class_to_idx = train_data.class_to_idx
class_names = train_data.classes
# print(f"Image shape: {image.shape}"
# f"{class_to_idx}")
#
# fig=plt.figure(figsize=(9,9))
# rows, cols = 4, 4
# for i in range(1,rows*cols+1):
# random_idx = torch.randint(low=0, high=len(train_data), size=[1]).item()
# img, label = train_data[random_idx]
# fig.add_subplot(rows, cols,i)
# print(f"random_idx: {random_idx} label: {label} img shape: {img.shape}")
#
# plt.imshow(img.squeeze(), cmap="gray")
# plt.title(class_names[label])
# plt.axis(False)
# #print(random_idx)
# # plt.imshow(image.squeeze(),cmap="gray")
# # plt.title(class_names[label])
# # plt.axis(False)
# plt.show()
train_features_batch, train_labels_batch = next(iter(train_dataloader))
flatten_model = nn.Flatten()
x = train_features_batch[0]
output = flatten_model(x)
train_time_start = timer()
model_0 = FashionMNISTModelV0(
input_shape=28*28,
hidden_units=10,
output_shape=len(class_names)
).to("cpu")
train_time_start = timer()
model_1 = FashionMNISTModelV1(
input_shape=28*28,
hidden_units=10,
output_shape=len(class_names)
).to(args.device)
model_2 = FashionMNISTModelV2(
input_shape=1,
hidden_units=10,
output_shape=len(class_names)
).to(args.device)
torch.manual_seed(42)
# Create sample batch of random numbers with same size as image batch
images = torch.randn(size=(32, 3, 64, 64)) # [batch_size, color_channels, height, width]
test_image = images[0] # get a single image for testing
torch.manual_seed(42)
# Create a convolutional layer with same dimensions as TinyVGG
# (try changing any of the parameters and see what happens)
conv_layer = nn.Conv2d(in_channels=3,
out_channels=10,
kernel_size=3,
stride=1,
padding=0) # also try using "valid" or "same" here
# Pass the data through the convolutional layer
#print(conv_layer(test_image)) # Note: If running PyTorch <1.11.0, this will error because of shape issues (nn.Conv.2d() expects a 4d tensor as input)
conv_layer_2 = nn.Conv2d(in_channels=3, # same number of color channels as our input image
out_channels=10,
kernel_size=(5, 5), # kernel is usually a square so a tuple also works
stride=2,
padding=0)
loss_fn = nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(params=model_2.parameters(),
lr=0.1)
#print(str(next(model_1.parameters()).device))
epochs = 3
#train_time_start_on_cpu = timer()
train_time_start_on_gpu = timer()
for epoch in tqdm(range(epochs)):
print(f"Epoch: {epoch}\n-------")
train_step(model=model_2,
data_loader=train_dataloader,
loss_fn=loss_fn,
optimizer=optimizer,
accuracy_fn=accuracy_fn,
device=args.device)
test_step(model=model_2,
data_loader=test_dataloader,
loss_fn=loss_fn,
accuracy_fn=accuracy_fn,
device=args.device)
#train_time_end_on_cpu = timer()
train_time_end_on_gpu = timer()
total_train_time_model_1 = print_train_time(start=train_time_start_on_gpu,
end=train_time_end_on_gpu,
device=args.device)
model_1_results = eval_model(model=model_1,
data_loader=test_dataloader,
loss_fn=loss_fn,
accuracy_fn=accuracy_fn,
device=args.device)
print(model_1_results)
Error is:
I am assuming the main error is: RuntimeError: The size of tensor a (7) must match the size of tensor b (10) at non-singleton dimension 3 and its within the FashionMNISTModelV2 class (self.classifier)
Code: