forked from eakbas/tf-svm
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlinear_svm.py
130 lines (102 loc) · 4.42 KB
/
linear_svm.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
import tensorflow as tf
import numpy as np
import scipy.io as io
from matplotlib import pyplot as plt
import plot_boundary_on_data
# Global variables.
BATCH_SIZE = 100 # The number of training examples to use per training step.
# Define the flags useable from the command line.
tf.app.flags.DEFINE_string('train', None,
'File containing the training data (labels & features).')
tf.app.flags.DEFINE_integer('num_epochs', 1,
'Number of training epochs.')
tf.app.flags.DEFINE_float('svmC', 1,
'The C parameter of the SVM cost function.')
tf.app.flags.DEFINE_boolean('verbose', False, 'Produce verbose output.')
tf.app.flags.DEFINE_boolean('plot', True, 'Plot the final decision boundary on the data.')
FLAGS = tf.app.flags.FLAGS
# Extract numpy representations of the labels and features given rows consisting of:
# label, feat_0, feat_1, ..., feat_n
# The given file should be a comma-separated-values (CSV) file saved by the savetxt command.
def extract_data(filename):
out = np.loadtxt(filename, delimiter=',');
# Arrays to hold the labels and feature vectors.
labels = out[:,0]
labels = labels.reshape(labels.size,1)
fvecs = out[:,1:]
# Return a pair of the feature matrix and the one-hot label matrix.
return fvecs,labels
def main(argv=None):
# Be verbose?
verbose = FLAGS.verbose
# Plot?
plot = FLAGS.plot
# Get the data.
train_data_filename = FLAGS.train
# Extract it into numpy matrices.
train_data,train_labels = extract_data(train_data_filename)
# Convert labels to +1,-1
train_labels[train_labels==0] = -1
# Get the shape of the training data.
train_size,num_features = train_data.shape
# Get the number of epochs for training.
num_epochs = FLAGS.num_epochs
# Get the C param of SVM
svmC = FLAGS.svmC
# This is where training samples and labels are fed to the graph.
# These placeholder nodes will be fed a batch of training data at each
# training step using the {feed_dict} argument to the Run() call below.
x = tf.placeholder("float", shape=[None, num_features])
y = tf.placeholder("float", shape=[None,1])
# Define and initialize the network.
# These are the weights that inform how much each feature contributes to
# the classification.
W = tf.Variable(tf.zeros([num_features,1]))
b = tf.Variable(tf.zeros([1]))
y_raw = tf.matmul(x,W) + b
# Optimization.
regularization_loss = 0.5*tf.reduce_sum(tf.square(W))
hinge_loss = tf.reduce_sum(tf.maximum(tf.zeros([BATCH_SIZE,1]),
1 - y*y_raw));
svm_loss = regularization_loss + svmC*hinge_loss;
train_step = tf.train.GradientDescentOptimizer(0.01).minimize(svm_loss)
# Evaluation.
predicted_class = tf.sign(y_raw);
correct_prediction = tf.equal(y,predicted_class)
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
# Create a local session to run this computation.
with tf.Session() as s:
# Run all the initializers to prepare the trainable parameters.
tf.initialize_all_variables().run()
if verbose:
print 'Initialized!'
print
print 'Training.'
# Iterate and train.
for step in xrange(num_epochs * train_size // BATCH_SIZE):
if verbose:
print step,
offset = (step * BATCH_SIZE) % train_size
batch_data = train_data[offset:(offset + BATCH_SIZE), :]
batch_labels = train_labels[offset:(offset + BATCH_SIZE)]
train_step.run(feed_dict={x: batch_data, y: batch_labels})
print 'loss: ', svm_loss.eval(feed_dict={x: batch_data, y: batch_labels})
if verbose and offset >= train_size-BATCH_SIZE:
print
# Give very detailed output.
if verbose:
print
print 'Weight matrix.'
print s.run(W)
print
print 'Bias vector.'
print s.run(b)
print
print "Applying model to first test instance."
print
print "Accuracy on train:", accuracy.eval(feed_dict={x: train_data, y: train_labels})
if plot:
eval_fun = lambda X: predicted_class.eval(feed_dict={x:X});
plot_boundary_on_data.plot(train_data, train_labels, eval_fun)
if __name__ == '__main__':
tf.app.run()