1 import numpy as np
2 from cs231n.classifiers.linear_svm import *
3 from cs231n.classifiers.softmax import *
4
5 class LinearClassifier(object):
6
7 def __init__(self):
8 self.W = None
9
10 def train(self, X, y, learning_rate=1e-3, reg=1e-5, num_iters=100,
11 batch_size=200, verbose=False):
12 """
13 Train this linear classifier using stochastic gradient descent.
14
15 Inputs:
16 - X: A numpy array of shape (N, D) containing training data; there are N
17 training samples each of dimension D.
18 - y: A numpy array of shape (N,) containing training labels; y[i] = c
19 means that X[i] has label 0 <= c < C for C classes.
20 - learning_rate: (float) learning rate for optimization.
21 - reg: (float) regularization strength.
22 - num_iters: (integer) number of steps to take when optimizing
23 - batch_size: (integer) number of training examples to use at each step.
24 - verbose: (boolean) If true, print progress during optimization.
25
26 Outputs:
27 A list containing the value of the loss function at each training iteration.
28 """
29 num_train, dim = X.shape
30 num_classes = np.max(y) + 1 # assume y takes values 0...K-1 where K is number of classes
31 if self.W is None:
32 # lazily initialize W
33 self.W = 0.001 * np.random.randn(dim, num_classes)
34
35 # Run stochastic gradient descent to optimize W
36 loss_history = []
37 for it in xrange(num_iters):
38 X_batch = None
39 y_batch = None
40
41 #########################################################################
42 # TODO: #
43 # Sample batch_size elements from the training data and their #
44 # corresponding labels to use in this round of gradient descent. #
45 # Store the data in X_batch and their corresponding labels in #
46 # y_batch; after sampling X_batch should have shape (dim, batch_size) #
47 # and y_batch should have shape (batch_size,) #
48 # #
49 # Hint: Use np.random.choice to generate indices. Sampling with #
50 # replacement is faster than sampling without replacement. #
51 #########################################################################
52 # num_train = 49000 batch_size = 200
53 mask = np.random.choice(num_train, batch_size, replace=False)
54 X_batch = X[mask]
55 y_batch = y[mask]
56 #########################################################################
57 # END OF YOUR CODE #
58 #########################################################################
59
60 # evaluate loss and gradient
61 loss, grad = self.loss(X_batch, y_batch, reg)
62 loss_history.append(loss)
63
64 # perform parameter update
65 #########################################################################
66 # TODO: #
67 # Update the weights using the gradient and the learning rate. #
68 #########################################################################
69 self.W = self.W - learning_rate * grad
70 #########################################################################
71 # END OF YOUR CODE #
72 #########################################################################
73
74 if verbose and it % 100 == 0:
75 print 'iteration %d / %d: loss %f' % (it, num_iters, loss)
76
77 return loss_history
78
79 def predict(self, X):
80 """
81 Use the trained weights of this linear classifier to predict labels for
82 data points.
83
84 Inputs:
85 - X: D x N array of training data. Each column is a D-dimensional point.
86
87 Returns:
88 - y_pred: Predicted labels for the data in X. y_pred is a 1-dimensional
89 array of length N, and each element is an integer giving the predicted
90 class.
91 """
92 y_pred = np.zeros(X.shape[1])
93 ###########################################################################
94 # TODO: #
95 # Implement this method. Store the predicted labels in y_pred. #
96 ###########################################################################
97 #49000*3073 * 3073 * 10
98 y_pred = np.argmax(np.dot(X,self.W), axis=1)
99 ###########################################################################
100 # END OF YOUR CODE #
101 ###########################################################################
102 return y_pred
103
104 def loss(self, X_batch, y_batch, reg):
105 """
106 Compute the loss function and its derivative.
107 Subclasses will override this.
108
109 Inputs:
110 - X_batch: A numpy array of shape (N, D) containing a minibatch of N
111 data points; each point has dimension D.
112 - y_batch: A numpy array of shape (N,) containing labels for the minibatch.
113 - reg: (float) regularization strength.
114
115 Returns: A tuple containing:
116 - loss as a single float
117 - gradient with respect to self.W; an array of the same shape as W
118 """
119 pass
120
121
122 class LinearSVM(LinearClassifier):
123 """ A subclass that uses the Multiclass SVM loss function """
124
125 def loss(self, X_batch, y_batch, reg):
126 return svm_loss_vectorized(self.W, X_batch, y_batch, reg)
127
128
129 class Softmax(LinearClassifier):
130 """ A subclass that uses the Softmax + Cross-entropy loss function """
131
132 def loss(self, X_batch, y_batch, reg):
133 return softmax_loss_vectorized(self.W, X_batch, y_batch, reg)