proj5 finished

This commit is contained in:
2025-11-14 10:46:33 +08:00
parent e71ae34bd1
commit 4da40089f5
4 changed files with 226 additions and 10 deletions

View File

@@ -37,7 +37,7 @@ class PerceptronModel(Module):
"""
super(PerceptronModel, self).__init__()
"*** YOUR CODE HERE ***"
self.w = Parameter(ones(1, dimensions))
def get_weights(self):
@@ -56,7 +56,7 @@ class PerceptronModel(Module):
The pytorch function `tensordot` may be helpful here.
"""
"*** YOUR CODE HERE ***"
return tensordot(self.w, x, dims=2)
def get_prediction(self, x):
@@ -65,7 +65,8 @@ class PerceptronModel(Module):
Returns: 1 or -1
"""
"*** YOUR CODE HERE ***"
score = self.run(x)
return 1 if score.item() >= 0 else -1
@@ -80,7 +81,17 @@ class PerceptronModel(Module):
"""
with no_grad():
dataloader = DataLoader(dataset, batch_size=1, shuffle=True)
"*** YOUR CODE HERE ***"
while True:
converged = True
for batch in dataloader:
x = batch['x']
y = batch['label']
prediction = self.get_prediction(x)
if prediction != y.item():
self.w.data += y.item() * x
converged = False
if converged:
break
@@ -94,6 +105,9 @@ class RegressionModel(Module):
# Initialize your model parameters here
"*** YOUR CODE HERE ***"
super().__init__()
self.layer1 = Linear(1, 256)
self.layer2 = Linear(256, 256)
self.layer3 = Linear(256, 1)
@@ -107,6 +121,9 @@ class RegressionModel(Module):
A node with shape (batch_size x 1) containing predicted y-values
"""
"*** YOUR CODE HERE ***"
x = relu(self.layer1(x))
x = relu(self.layer2(x))
return self.layer3(x)
def get_loss(self, x, y):
@@ -120,6 +137,7 @@ class RegressionModel(Module):
Returns: a tensor of size 1 containing the loss
"""
"*** YOUR CODE HERE ***"
return mse_loss(self.forward(x), y)
@@ -138,6 +156,27 @@ class RegressionModel(Module):
"""
"*** YOUR CODE HERE ***"
batch_size = 40
dataloader = DataLoader(dataset, batch_size=batch_size, shuffle=True)
optimizer = optim.Adam(self.parameters(), lr=0.001)
scheduler = optim.lr_scheduler.StepLR(optimizer, step_size=250, gamma=0.1)
for epoch in range(1000): # Train for 1000 epochs, should be enough
total_loss = 0
num_samples = 0
for batch in dataloader:
optimizer.zero_grad()
loss = self.get_loss(batch['x'], batch['label'])
loss.backward()
optimizer.step()
total_loss += loss.item() * len(batch['x'])
num_samples += len(batch['x'])
scheduler.step()
avg_loss = total_loss / num_samples
if avg_loss < 0.02:
break
@@ -167,6 +206,9 @@ class DigitClassificationModel(Module):
input_size = 28 * 28
output_size = 10
"*** YOUR CODE HERE ***"
self.layer1 = Linear(input_size, 256)
self.layer2 = Linear(256, 128)
self.layer3 = Linear(128, output_size)
@@ -186,6 +228,9 @@ class DigitClassificationModel(Module):
(also called logits)
"""
""" YOUR CODE HERE """
x = relu(self.layer1(x))
x = relu(self.layer2(x))
return self.layer3(x)
@@ -203,6 +248,7 @@ class DigitClassificationModel(Module):
Returns: a loss tensor
"""
""" YOUR CODE HERE """
return cross_entropy(self.run(x), y)
@@ -212,6 +258,16 @@ class DigitClassificationModel(Module):
Trains the model.
"""
""" YOUR CODE HERE """
batch_size = 100
dataloader = DataLoader(dataset, batch_size=batch_size, shuffle=True)
optimizer = optim.Adam(self.parameters(), lr=0.001)
for epoch in range(5): # Train for 5 epochs
for batch in dataloader:
optimizer.zero_grad()
loss = self.get_loss(batch['x'], batch['label'])
loss.backward()
optimizer.step()
@@ -314,13 +370,18 @@ def Convolve(input: tensor, weight: tensor):
This returns a subtensor who's first element is tensor[y,x] and has height 'height, and width 'width'
"""
input_tensor_dimensions = input.shape
weight_dimensions = weight.shape
Output_Tensor = tensor(())
"*** YOUR CODE HERE ***"
input_h, input_w = input.shape
weight_h, weight_w = weight.shape
output_h = input_h - weight_h + 1
output_w = input_w - weight_w + 1
"*** End Code ***"
Output_Tensor = torch.zeros((output_h, output_w))
for y in range(output_h):
for x in range(output_w):
sub_tensor = input[y:y+weight_h, x:x+weight_w]
Output_Tensor[y, x] = tensordot(sub_tensor, weight, dims=2)
return Output_Tensor
@@ -345,6 +406,10 @@ class DigitConvolutionalModel(Module):
self.convolution_weights = Parameter(ones((3, 3)))
""" YOUR CODE HERE """
conv_output_size = 26 * 26
hidden_size = 100
self.layer1 = Linear(conv_output_size, hidden_size)
self.layer2 = Linear(hidden_size, output_size)
@@ -361,6 +426,8 @@ class DigitConvolutionalModel(Module):
x = stack(list(map(lambda sample: Convolve(sample, self.convolution_weights), x)))
x = x.flatten(start_dim=1)
""" YOUR CODE HERE """
x = relu(self.layer1(x))
return self.layer2(x)
def get_loss(self, x, y):
@@ -377,6 +444,7 @@ class DigitConvolutionalModel(Module):
Returns: a loss tensor
"""
""" YOUR CODE HERE """
return cross_entropy(self.forward(x), y)
@@ -386,6 +454,16 @@ class DigitConvolutionalModel(Module):
Trains the model.
"""
""" YOUR CODE HERE """
batch_size = 64
dataloader = DataLoader(dataset, batch_size=batch_size, shuffle=True)
optimizer = optim.Adam(self.parameters(), lr=0.001)
for epoch in range(3):
for batch in dataloader:
optimizer.zero_grad()
loss = self.get_loss(batch['x'], batch['label'])
loss.backward()
optimizer.step()