-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 5511fdf
Showing
58 changed files
with
10,287 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
anaconda-2.4.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
*.swp | ||
*.pyc | ||
.env/* |
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
anaconda-2.4.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Details about this assignment can be found [on the course webpage](http://cs231n.github.io/), under Assignment #1 of Winter 2016. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
rm -f assignment1.zip | ||
zip -r assignment1.zip . -x "*.git*" "*cs231n/datasets*" "*.ipynb_checkpoints*" "*README.md" "*collectSubmission.sh" "*requirements.txt" |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
from cs231n.classifiers.k_nearest_neighbor import * | ||
from cs231n.classifiers.linear_classifier import * |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,188 @@ | ||
import numpy as np | ||
|
||
class KNearestNeighbor(object): | ||
""" a kNN classifier with L2 distance """ | ||
|
||
def __init__(self): | ||
pass | ||
|
||
def train(self, X, y): | ||
""" | ||
Train the classifier. For k-nearest neighbors this is just | ||
memorizing the training data. | ||
Inputs: | ||
- X: A numpy array of shape (num_train, D) containing the training data | ||
consisting of num_train samples each of dimension D. | ||
- y: A numpy array of shape (N,) containing the training labels, where | ||
y[i] is the label for X[i]. | ||
""" | ||
self.X_train = X | ||
self.y_train = y | ||
|
||
def predict(self, X, k=1, num_loops=0): | ||
""" | ||
Predict labels for test data using this classifier. | ||
Inputs: | ||
- X: A numpy array of shape (num_test, D) containing test data consisting | ||
of num_test samples each of dimension D. | ||
- k: The number of nearest neighbors that vote for the predicted labels. | ||
- num_loops: Determines which implementation to use to compute distances | ||
between training points and testing points. | ||
Returns: | ||
- y: A numpy array of shape (num_test,) containing predicted labels for the | ||
test data, where y[i] is the predicted label for the test point X[i]. | ||
""" | ||
if num_loops == 0: | ||
dists = self.compute_distances_no_loops(X) | ||
elif num_loops == 1: | ||
dists = self.compute_distances_one_loop(X) | ||
elif num_loops == 2: | ||
dists = self.compute_distances_two_loops(X) | ||
else: | ||
raise ValueError('Invalid value %d for num_loops' % num_loops) | ||
|
||
return self.predict_labels(dists, k=k) | ||
|
||
def compute_distances_two_loops(self, X): | ||
""" | ||
Compute the distance between each test point in X and each training point | ||
in self.X_train using a nested loop over both the training data and the | ||
test data. | ||
Inputs: | ||
- X: A numpy array of shape (num_test, D) containing test data. | ||
Returns: | ||
- dists: A numpy array of shape (num_test, num_train) where dists[i, j] | ||
is the Euclidean distance between the ith test point and the jth training | ||
point. | ||
""" | ||
num_test = X.shape[0] | ||
num_train = self.X_train.shape[0] | ||
dists = np.zeros((num_test, num_train)) | ||
for i in xrange(num_test): | ||
for j in xrange(num_train): | ||
##################################################################### | ||
# TODO: # | ||
# Compute the l2 distance between the ith test point and the jth # | ||
# training point, and store the result in dists[i, j]. You should # | ||
# not use a loop over dimension. # | ||
##################################################################### | ||
thesum = np.sum((X[i] - self.X_train[j])**2) | ||
dists[i, j] = np.sqrt(thesum) | ||
##################################################################### | ||
# END OF YOUR CODE # | ||
##################################################################### | ||
return dists | ||
|
||
def compute_distances_one_loop(self, X): | ||
""" | ||
Compute the distance between each test point in X and each training point | ||
in self.X_train using a single loop over the test data. | ||
Input / Output: Same as compute_distances_two_loops | ||
""" | ||
num_test = X.shape[0] | ||
num_train = self.X_train.shape[0] | ||
dists = np.zeros((num_test, num_train)) | ||
for i in xrange(num_test): | ||
####################################################################### | ||
# TODO: # | ||
# Compute the l2 distance between the ith test point and all training # | ||
# points, and store the result in dists[i, :]. # | ||
####################################################################### | ||
dists[i, :] = np.sqrt(np.sum((X[i] - self.X_train)**2, 1)) | ||
####################################################################### | ||
# END OF YOUR CODE # | ||
####################################################################### | ||
return dists | ||
|
||
def compute_distances_no_loops(self, X): | ||
""" | ||
Compute the distance between each test point in X and each training point | ||
in self.X_train using no explicit loops. | ||
Input / Output: Same as compute_distances_two_loops | ||
""" | ||
num_test = X.shape[0] | ||
num_train = self.X_train.shape[0] | ||
dists = np.zeros((num_test, num_train)) | ||
######################################################################### | ||
# TODO: # | ||
# Compute the l2 distance between all test points and all training # | ||
# points without using any explicit loops, and store the result in # | ||
# dists. # | ||
# # | ||
# You should implement this function using only basic array operations; # | ||
# in particular you should not use functions from scipy. # | ||
# # | ||
# HINT: Try to formulate the l2 distance using matrix multiplication # | ||
# and two broadcast sums. # | ||
######################################################################### | ||
x2 = np.sum(X**2, 1, keepdims=True) | ||
y2 = np.sum(self.X_train**2, 1, keepdims=True) | ||
xy = np.dot(X, self.X_train.T) | ||
dists = np.sqrt(x2 - (2 * xy) + y2.T) | ||
|
||
######################################################################### | ||
# END OF YOUR CODE # | ||
######################################################################### | ||
return dists | ||
|
||
def predict_labels(self, dists, k=1): | ||
""" | ||
Given a matrix of distances between test points and training points, | ||
predict a label for each test point. | ||
Inputs: | ||
- dists: A numpy array of shape (num_test, num_train) where dists[i, j] | ||
gives the distance betwen the ith test point and the jth training point. | ||
Returns: | ||
- y: A numpy array of shape (num_test,) containing predicted labels for the | ||
test data, where y[i] is the predicted label for the test point X[i]. | ||
""" | ||
num_labels = max(self.y_train) + 1 | ||
num_test = dists.shape[0] | ||
y_pred = np.zeros(num_test) | ||
for i in xrange(num_test): | ||
# A list of length k storing the labels of the k nearest neighbors to | ||
# the ith test point. | ||
closest_y = [] | ||
######################################################################### | ||
# TODO: # | ||
# Use the distance matrix to find the k nearest neighbors of the ith # | ||
# testing point, and use self.y_train to find the labels of these # | ||
# neighbors. Store these labels in closest_y. # | ||
# Hint: Look up the function numpy.argsort. # | ||
######################################################################### | ||
#print("dists[i]", dists[i][0:10]) | ||
#print(np.shape(dists[i])) | ||
|
||
idx_array = np.argsort(dists[i]) | ||
#print("dists[i] SORTED", dists[i][idx_array][0:10]) | ||
closest_y = self.y_train[idx_array][0:k] | ||
#print("closest labels", closest_y) | ||
######################################################################### | ||
# TODO: # | ||
# Now that you have found the labels of the k nearest neighbors, you # | ||
# need to find the most common label in the list closest_y of labels. # | ||
# Store this label in y_pred[i]. Break ties by choosing the smaller # | ||
# label. # | ||
######################################################################### | ||
#print(max(self.y_train)) | ||
y_accu = [ sum(closest_y == j) for j in xrange(num_labels) ] | ||
|
||
|
||
y_pred[i] = np.argmax(y_accu) | ||
|
||
|
||
######################################################################### | ||
# END OF YOUR CODE # | ||
######################################################################### | ||
|
||
return y_pred | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
import numpy as np | ||
from cs231n.classifiers.linear_svm import * | ||
from cs231n.classifiers.softmax import * | ||
|
||
class LinearClassifier(object): | ||
|
||
def __init__(self): | ||
self.W = None | ||
|
||
def train(self, X, y, learning_rate=1e-3, reg=1e-5, num_iters=100, | ||
batch_size=200, verbose=False): | ||
""" | ||
Train this linear classifier using stochastic gradient descent. | ||
Inputs: | ||
- X: A numpy array of shape (N, D) containing training data; there are N | ||
training samples each of dimension D. | ||
- y: A numpy array of shape (N,) containing training labels; y[i] = c | ||
means that X[i] has label 0 <= c < C for C classes. | ||
- learning_rate: (float) learning rate for optimization. | ||
- reg: (float) regularization strength. | ||
- num_iters: (integer) number of steps to take when optimizing | ||
- batch_size: (integer) number of training examples to use at each step. | ||
- verbose: (boolean) If true, print progress during optimization. | ||
Outputs: | ||
A list containing the value of the loss function at each training iteration. | ||
""" | ||
num_train, dim = X.shape | ||
num_classes = np.max(y) + 1 # assume y takes values 0...K-1 where K is number of classes | ||
if self.W is None: | ||
# lazily initialize W | ||
self.W = 0.001 * np.random.randn(dim, num_classes) | ||
|
||
# Run stochastic gradient descent to optimize W | ||
loss_history = [] | ||
for it in xrange(num_iters): | ||
X_batch = None | ||
y_batch = None | ||
|
||
######################################################################### | ||
# TODO: # | ||
# Sample batch_size elements from the training data and their # | ||
# corresponding labels to use in this round of gradient descent. # | ||
# Store the data in X_batch and their corresponding labels in # | ||
# y_batch; after sampling X_batch should have shape (dim, batch_size) # | ||
# and y_batch should have shape (batch_size,) # | ||
# # | ||
# Hint: Use np.random.choice to generate indices. Sampling with # | ||
# replacement is faster than sampling without replacement. # | ||
######################################################################### | ||
pass | ||
######################################################################### | ||
# END OF YOUR CODE # | ||
######################################################################### | ||
|
||
# evaluate loss and gradient | ||
loss, grad = self.loss(X_batch, y_batch, reg) | ||
loss_history.append(loss) | ||
|
||
# perform parameter update | ||
######################################################################### | ||
# TODO: # | ||
# Update the weights using the gradient and the learning rate. # | ||
######################################################################### | ||
pass | ||
######################################################################### | ||
# END OF YOUR CODE # | ||
######################################################################### | ||
|
||
if verbose and it % 100 == 0: | ||
print 'iteration %d / %d: loss %f' % (it, num_iters, loss) | ||
|
||
return loss_history | ||
|
||
def predict(self, X): | ||
""" | ||
Use the trained weights of this linear classifier to predict labels for | ||
data points. | ||
Inputs: | ||
- X: D x N array of training data. Each column is a D-dimensional point. | ||
Returns: | ||
- y_pred: Predicted labels for the data in X. y_pred is a 1-dimensional | ||
array of length N, and each element is an integer giving the predicted | ||
class. | ||
""" | ||
y_pred = np.zeros(X.shape[1]) | ||
########################################################################### | ||
# TODO: # | ||
# Implement this method. Store the predicted labels in y_pred. # | ||
########################################################################### | ||
pass | ||
########################################################################### | ||
# END OF YOUR CODE # | ||
########################################################################### | ||
return y_pred | ||
|
||
def loss(self, X_batch, y_batch, reg): | ||
""" | ||
Compute the loss function and its derivative. | ||
Subclasses will override this. | ||
Inputs: | ||
- X_batch: A numpy array of shape (N, D) containing a minibatch of N | ||
data points; each point has dimension D. | ||
- y_batch: A numpy array of shape (N,) containing labels for the minibatch. | ||
- reg: (float) regularization strength. | ||
Returns: A tuple containing: | ||
- loss as a single float | ||
- gradient with respect to self.W; an array of the same shape as W | ||
""" | ||
pass | ||
|
||
|
||
class LinearSVM(LinearClassifier): | ||
""" A subclass that uses the Multiclass SVM loss function """ | ||
|
||
def loss(self, X_batch, y_batch, reg): | ||
return svm_loss_vectorized(self.W, X_batch, y_batch, reg) | ||
|
||
|
||
class Softmax(LinearClassifier): | ||
""" A subclass that uses the Softmax + Cross-entropy loss function """ | ||
|
||
def loss(self, X_batch, y_batch, reg): | ||
return softmax_loss_vectorized(self.W, X_batch, y_batch, reg) | ||
|
Oops, something went wrong.