ml q5
This commit is contained in:
@ -576,7 +576,7 @@ def check_convolution(tracker):
|
||||
input = torch.rand(matrix_size, matrix_size)
|
||||
student_output = models.Convolve(input, weights)
|
||||
actual_output = conv2d(input,weights)
|
||||
assert torch.isclose(student_output, actual_output).all(), "The convolution returned by Convolve() does not match expected output"
|
||||
assert torch.isclose(student_output.cpu(), actual_output).all(), "The convolution returned by Convolve() does not match expected output"
|
||||
|
||||
tracker.add_points(1/2) # Partial credit for testing whether convolution function works
|
||||
|
||||
|
@ -492,7 +492,7 @@ class DigitClassificationDataset2(CustomDataset):
|
||||
def get_validation_accuracy(self):
|
||||
dev_logits = self.model.run(torch.tensor(self.dev_images, dtype=torch.float32)).data
|
||||
dev_predicted = torch.argmax(dev_logits, axis=1).detach()
|
||||
dev_accuracy = torch.mean(torch.eq(dev_predicted, torch.tensor(self.dev_labels)).float())
|
||||
dev_accuracy = torch.mean(torch.eq(dev_predicted.cpu(), torch.tensor(self.dev_labels)).float())
|
||||
return dev_accuracy
|
||||
|
||||
def main():
|
||||
|
@ -457,15 +457,28 @@ 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_tensor_height, input_tensor_width = input.shape
|
||||
weight_height, weight_width = weight.shape
|
||||
|
||||
# Calculate output dimensions
|
||||
output_height = input_tensor_height - weight_height + 1
|
||||
output_width = input_tensor_width - weight_width + 1
|
||||
|
||||
"*** End Code ***"
|
||||
return Output_Tensor
|
||||
# Initialize output tensor
|
||||
if input.device.type!=Convolve.device.type:
|
||||
input=input.to(Convolve.device)
|
||||
if weight.device.type!=Convolve.device.type:
|
||||
weight=weight.to(Convolve.device)
|
||||
output = torch.zeros((output_height, output_width),device=Convolve.device)
|
||||
|
||||
# Perform convolution
|
||||
for i in range(output_height):
|
||||
for j in range(output_width):
|
||||
output[i, j] = torch.tensordot(input[i:i+weight_height, j:j+weight_width], weight, dims=2)
|
||||
|
||||
return output
|
||||
|
||||
Convolve.device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
||||
|
||||
|
||||
class DigitConvolutionalModel(Module):
|
||||
@ -484,9 +497,17 @@ class DigitConvolutionalModel(Module):
|
||||
# Initialize your model parameters here
|
||||
super().__init__()
|
||||
output_size = 10
|
||||
|
||||
self.convolution_weights = Parameter(ones((3, 3)))
|
||||
self.device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
||||
self.convolution_weights = Parameter(ones((3, 3))).to(self.device)
|
||||
""" YOUR CODE HERE """
|
||||
flatten_size = 26 * 26
|
||||
linear1_size = 300
|
||||
linear2_size = 300
|
||||
linear3_size = 300
|
||||
self.fc1=Linear(flatten_size, linear1_size).to(self.device)
|
||||
self.fc_out = Linear(linear1_size, output_size).to(self.device)
|
||||
# self.fc2 = Linear(linear1_size, linear2_size).to(self.device)
|
||||
# self.fc3 = Linear(linear2_size, output_size).to(self.device)
|
||||
|
||||
|
||||
def run(self, x):
|
||||
@ -494,10 +515,18 @@ class DigitConvolutionalModel(Module):
|
||||
The convolutional layer is already applied, and the output is flattened for you. You should treat x as
|
||||
a regular 1-dimentional datapoint now, similar to the previous questions.
|
||||
"""
|
||||
# print(f"now x={x}")
|
||||
x = x.reshape(len(x), 28, 28)
|
||||
x = stack(list(map(lambda sample: Convolve(sample, self.convolution_weights), x)))
|
||||
# print(f"now x={x}")
|
||||
x = x.flatten(start_dim=1)
|
||||
""" YOUR CODE HERE """
|
||||
# x=x.to(self.device)
|
||||
x=torch.relu(self.fc1(x))
|
||||
x = self.fc_out(x)
|
||||
# x = torch.relu(self.fc2(x))
|
||||
# x = torch.relu(self.fc3(x))
|
||||
return x
|
||||
|
||||
|
||||
|
||||
@ -515,6 +544,13 @@ class DigitConvolutionalModel(Module):
|
||||
Returns: a loss tensor
|
||||
"""
|
||||
""" YOUR CODE HERE """
|
||||
# print(f"x={x},y={y}")
|
||||
# print(f"self.run(x.to(self.device))={self.run(x.to(self.device))}")
|
||||
if x.device.type!=self.device.type:
|
||||
x=x.to(self.device)
|
||||
if y.device.type!=self.device.type:
|
||||
y=y.to(self.device)
|
||||
return cross_entropy(self.run(x), y)
|
||||
|
||||
|
||||
|
||||
@ -523,4 +559,25 @@ class DigitConvolutionalModel(Module):
|
||||
Trains the model.
|
||||
"""
|
||||
""" YOUR CODE HERE """
|
||||
optimizer = torch.optim.Adam(self.parameters(), lr=0.001)
|
||||
dataloader = DataLoader(dataset, batch_size=10, shuffle=True)
|
||||
max_round=30000
|
||||
required_accuracy=0.99
|
||||
round_cnt=0
|
||||
while round_cnt<max_round:
|
||||
for sample in dataloader:
|
||||
x = sample['x'].to(self.device)
|
||||
y = sample['label'].to(self.device)
|
||||
loss = self.get_loss(x, y)
|
||||
if dataset.get_validation_accuracy() > required_accuracy:
|
||||
break
|
||||
optimizer.zero_grad()
|
||||
loss.backward()
|
||||
optimizer.step()
|
||||
round_cnt+=1
|
||||
if round_cnt%1==0:
|
||||
print(f"round: {round_cnt}, accuracy: {dataset.get_validation_accuracy()}")
|
||||
if dataset.get_validation_accuracy() > required_accuracy:
|
||||
break
|
||||
print(f"round: {round_cnt}, accuracy: {dataset.get_validation_accuracy()}")
|
||||
|
Reference in New Issue
Block a user