ml q5
This commit is contained in:
@ -576,7 +576,7 @@ def check_convolution(tracker):
|
|||||||
input = torch.rand(matrix_size, matrix_size)
|
input = torch.rand(matrix_size, matrix_size)
|
||||||
student_output = models.Convolve(input, weights)
|
student_output = models.Convolve(input, weights)
|
||||||
actual_output = conv2d(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
|
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):
|
def get_validation_accuracy(self):
|
||||||
dev_logits = self.model.run(torch.tensor(self.dev_images, dtype=torch.float32)).data
|
dev_logits = self.model.run(torch.tensor(self.dev_images, dtype=torch.float32)).data
|
||||||
dev_predicted = torch.argmax(dev_logits, axis=1).detach()
|
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
|
return dev_accuracy
|
||||||
|
|
||||||
def main():
|
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'
|
This returns a subtensor who's first element is tensor[y,x] and has height 'height, and width 'width'
|
||||||
"""
|
"""
|
||||||
input_tensor_dimensions = input.shape
|
input_tensor_height, input_tensor_width = input.shape
|
||||||
weight_dimensions = weight.shape
|
weight_height, weight_width = weight.shape
|
||||||
Output_Tensor = tensor(())
|
|
||||||
"*** YOUR CODE HERE ***"
|
|
||||||
|
|
||||||
|
|
||||||
"*** End Code ***"
|
# Calculate output dimensions
|
||||||
return Output_Tensor
|
output_height = input_tensor_height - weight_height + 1
|
||||||
|
output_width = input_tensor_width - weight_width + 1
|
||||||
|
|
||||||
|
# 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):
|
class DigitConvolutionalModel(Module):
|
||||||
@ -484,9 +497,17 @@ class DigitConvolutionalModel(Module):
|
|||||||
# Initialize your model parameters here
|
# Initialize your model parameters here
|
||||||
super().__init__()
|
super().__init__()
|
||||||
output_size = 10
|
output_size = 10
|
||||||
|
self.device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
||||||
self.convolution_weights = Parameter(ones((3, 3)))
|
self.convolution_weights = Parameter(ones((3, 3))).to(self.device)
|
||||||
""" YOUR CODE HERE """
|
""" 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):
|
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
|
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.
|
a regular 1-dimentional datapoint now, similar to the previous questions.
|
||||||
"""
|
"""
|
||||||
|
# print(f"now x={x}")
|
||||||
x = x.reshape(len(x), 28, 28)
|
x = x.reshape(len(x), 28, 28)
|
||||||
x = stack(list(map(lambda sample: Convolve(sample, self.convolution_weights), x)))
|
x = stack(list(map(lambda sample: Convolve(sample, self.convolution_weights), x)))
|
||||||
|
# print(f"now x={x}")
|
||||||
x = x.flatten(start_dim=1)
|
x = x.flatten(start_dim=1)
|
||||||
""" YOUR CODE HERE """
|
""" 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
|
Returns: a loss tensor
|
||||||
"""
|
"""
|
||||||
""" YOUR CODE HERE """
|
""" 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.
|
Trains the model.
|
||||||
"""
|
"""
|
||||||
""" YOUR CODE HERE """
|
""" 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