Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
brightredchilli committed Mar 8, 2016
0 parents commit 5511fdf
Show file tree
Hide file tree
Showing 58 changed files with 10,287 additions and 0 deletions.
1 change: 1 addition & 0 deletions .python-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
anaconda-2.4.0
3 changes: 3 additions & 0 deletions assignment1/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
*.swp
*.pyc
.env/*
748 changes: 748 additions & 0 deletions assignment1/.ipynb_checkpoints/knn-checkpoint.ipynb

Large diffs are not rendered by default.

686 changes: 686 additions & 0 deletions assignment1/.ipynb_checkpoints/svm-checkpoint.ipynb

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions assignment1/.python-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
anaconda-2.4.0
1 change: 1 addition & 0 deletions assignment1/README.md
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.
2 changes: 2 additions & 0 deletions assignment1/collectSubmission.sh
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 added assignment1/cs231n/__init__.py
Empty file.
2 changes: 2 additions & 0 deletions assignment1/cs231n/classifiers/__init__.py
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 *
188 changes: 188 additions & 0 deletions assignment1/cs231n/classifiers/k_nearest_neighbor.py
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

130 changes: 130 additions & 0 deletions assignment1/cs231n/classifiers/linear_classifier.py
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)

Loading

0 comments on commit 5511fdf

Please sign in to comment.