mirror of https://github.com/da0c/DL_Course_SamU
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
140 lines
5.6 KiB
Python
140 lines
5.6 KiB
Python
from __future__ import print_function
|
|
|
|
from builtins import range
|
|
from builtins import object
|
|
import numpy as np
|
|
from scripts.classifiers.linear_svm import *
|
|
from scripts.classifiers.softmax import *
|
|
from past.builtins import xrange
|
|
|
|
|
|
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 range(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 (batch_size, dim) #
|
|
# 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. #
|
|
#########################################################################
|
|
# *****START OF YOUR CODE (DO NOT DELETE/MODIFY THIS LINE)*****
|
|
|
|
pass
|
|
|
|
# *****END OF YOUR CODE (DO NOT DELETE/MODIFY THIS LINE)*****
|
|
|
|
# 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. #
|
|
#########################################################################
|
|
# *****START OF YOUR CODE (DO NOT DELETE/MODIFY THIS LINE)*****
|
|
|
|
pass
|
|
|
|
# *****END OF YOUR CODE (DO NOT DELETE/MODIFY THIS LINE)*****
|
|
|
|
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: A numpy array of shape (N, D) containing training data; there are N
|
|
training samples each of dimension D.
|
|
|
|
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[0])
|
|
###########################################################################
|
|
# TODO: #
|
|
# Implement this method. Store the predicted labels in y_pred. #
|
|
###########################################################################
|
|
# *****START OF YOUR CODE (DO NOT DELETE/MODIFY THIS LINE)*****
|
|
|
|
pass
|
|
|
|
# *****END OF YOUR CODE (DO NOT DELETE/MODIFY THIS LINE)*****
|
|
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)
|