Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Building an SVM with Tensorflow

I currently have two numpy arrays:

  • X - (157, 128) - 157 sets of 128 features
  • Y - (157) - classifications of the feature sets

This is the code I have written to attempt to build a linear classification model of these features.

First of all I adapted the arrays to a Tensorflow dataset:

train_input_fn = tf.estimator.inputs.numpy_input_fn(
    x={"x": X},
    y=Y,
    num_epochs=None,
    shuffle=True)

I then tried to fit an SVM model:

svm = tf.contrib.learn.SVM(
    example_id_column='example_id', # not sure why this is necessary
    feature_columns=tf.contrib.learn.infer_real_valued_columns_from_input(X), # create feature columns (not sure why this is necessary) 
    l2_regularization=0.1)

svm.fit(input_fn=train_input_fn, steps=10)

But this just returns the error:

WARNING:tensorflow:float64 is not supported by many models, consider casting to float32.
WARNING:tensorflow:Using temporary folder as model directory: /tmp/tmpf1mwlR
WARNING:tensorflow:tf.variable_op_scope(values, name, default_name) is deprecated, use tf.variable_scope(name, default_name, values)
Traceback (most recent call last):
  File "/var/www/idmy.team/python/train/classifier.py", line 59, in <module>
    svm.fit(input_fn=train_input_fn, steps=10)
  File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/util/deprecation.py", line 316, in new_func
    return func(*args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/tensorflow/contrib/learn/python/learn/estimators/estimator.py", line 480, in fit
    loss = self._train_model(input_fn=input_fn, hooks=hooks)
  File "/usr/local/lib/python2.7/dist-packages/tensorflow/contrib/learn/python/learn/estimators/estimator.py", line 985, in _train_model
    model_fn_ops = self._get_train_ops(features, labels)
  File "/usr/local/lib/python2.7/dist-packages/tensorflow/contrib/learn/python/learn/estimators/estimator.py", line 1201, in _get_train_ops
    return self._call_model_fn(features, labels, model_fn_lib.ModeKeys.TRAIN)
  File "/usr/local/lib/python2.7/dist-packages/tensorflow/contrib/learn/python/learn/estimators/estimator.py", line 1165, in _call_model_fn
    model_fn_results = self._model_fn(features, labels, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/tensorflow/contrib/learn/python/learn/estimators/linear.py", line 244, in sdca_model_fn
    features.update(layers.transform_features(features, feature_columns))
  File "/usr/local/lib/python2.7/dist-packages/tensorflow/contrib/layers/python/layers/feature_column_ops.py", line 656, in transform_features
    transformer.transform(column)
  File "/usr/local/lib/python2.7/dist-packages/tensorflow/contrib/layers/python/layers/feature_column_ops.py", line 847, in transform
    feature_column.insert_transformed_feature(self._columns_to_tensors)
  File "/usr/local/lib/python2.7/dist-packages/tensorflow/contrib/layers/python/layers/feature_column.py", line 1816, in insert_transformed_feature
    input_tensor = self._normalized_input_tensor(columns_to_tensors[self.name])
KeyError: ''

What am I doing wrong?

like image 901
maxisme Avatar asked Mar 24 '18 14:03

maxisme


People also ask

Can SVM be better than neural networks?

What's more important, though, is that they both perform with comparable accuracy against the same dataset, if given comparable training. If given as much training and computational power as possible, however, NNs tend to outperform SVMs.

Can we use SVM in deep learning?

They can not be same but can be used together. Deep learning is more powerfull classifier than SVM. However there are many difficulties to use DL. So if you can use SVM and have good performance,then use SVM.

Is SVM better than MLP?

SVMs based on the minimization of the structural risk, whereas MLP classifiers implement empirical risk minimization. So, SVMs are efficient and generate near the best classification as they obtain the optimum separating surface which has good performance on previously unseen data points.

Can we use SVM in neural network?

The Neural Support Vector Machine (NSVM) is a hybrid learning algorithm consisting of neural networks and support vector machines (SVMs). The output of the NSVM is given by SVMs that take a central feature layer as their input.


2 Answers

Here's an SVM usage example which does not throw an error:

import numpy
import tensorflow as tf

X = numpy.zeros([157, 128])
Y = numpy.zeros([157], dtype=numpy.int32)
example_id = numpy.array(['%d' % i for i in range(len(Y))])

x_column_name = 'x'
example_id_column_name = 'example_id'

train_input_fn = tf.estimator.inputs.numpy_input_fn(
    x={x_column_name: X, example_id_column_name: example_id},
    y=Y,
    num_epochs=None,
    shuffle=True)

svm = tf.contrib.learn.SVM(
    example_id_column=example_id_column_name,
    feature_columns=(tf.contrib.layers.real_valued_column(
        column_name=x_column_name, dimension=128),),
    l2_regularization=0.1)

svm.fit(input_fn=train_input_fn, steps=10)

Examples passed to the SVM Estimator need string IDs. You can probably substitute back infer_real_valued_columns_from_input, but you would need to pass it a dictionary so it picks up the right name for the column. In this case it's conceptually simpler to just construct the feature column yourself.

like image 56
Allen Lavoie Avatar answered Oct 04 '22 04:10

Allen Lavoie


  • The key self.name is not present in column_to_tensors dictionary that's what the error says and the value of self.name is an empty string
  • I think you messed up in giving the arguments to tf.estimator.inputs.numpy_input_fn
  • The solution might be changing train_input_fn line to

    train_input_fn = tf.estimator.inputs.numpy_input_fn(x=X,
                                                        y=Y,
                                                        num_epochs=None,
                                                        shuffle=True)
    
  • I think the x argument has to be a numpy array and you are giving it a dictionary

  • I will stick to their tutorial and do not do any fancy

    real_feature_column = real_valued_column(...)
    sparse_feature_column = sparse_column_with_hash_bucket(...)
    
    estimator = SVM(
        example_id_column='example_id',
        feature_columns=[real_feature_column, sparse_feature_column],
        l2_regularization=10.0)
    
    # Input builders
    def input_fn_train: # returns x, y
        ...
    def input_fn_eval: # returns x, y
        ...
    
    estimator.fit(input_fn=input_fn_train)
    estimator.evaluate(input_fn=input_fn_eval)
    estimator.predict(x=x)
    

===============UPDATED==============

  • My updated answer will be specific to your error
  • As the error says self.name is an empty string and that empty string is not present in your dictionary that you are passing to infer_real_valued_columns_from_input that creates _RealValuedColumn object
  • So What I found by debugging the error is that the tf.contrib.learn.infer_real_valued_columns_from_input(X) the X that you pass has to be a dictionary so that the self.name of _RealValuedColumn object is initialized by the key of the dictionary that you pass
  • So this is what I did

    import tensorflow as tf
    import numpy as np
    
    X = np.array([[1], [0], [0], [1]])
    Y = np.array([[1], [0], [0], [1]])
    
    dic = {"x": X}
    
    train_input_fn = tf.estimator.inputs.numpy_input_fn(
        x=dic,
        y=Y,
        num_epochs=None,
        shuffle=True)
    
    svm = tf.contrib.learn.SVM(example_id_column='x', feature_columns=tf.contrib.learn.infer_real_valued_columns_from_input(dic), l2_regularization=0.1)
    
    svm.fit(input_fn=train_input_fn, steps=10)
    
  • Now this removes the above error an but it gives a new error TypeError: Input 'input' of 'SdcaFprint' Op has type int64 that does not match expected type of string.

  • Hopefully you remove your down-vote
like image 36
Jai Avatar answered Oct 04 '22 02:10

Jai