The TensorFlow Code Library vs. CNTK and Keras

TensorFlow (TF) is arguably the best-known code library for creating deep neural networks. I hadn’t looked at TF in a couple of months so I thought I’d revisit.

The bottom line: I much prefer the CNTK library, or the Keras wrapper library over TF.

There are many code libraries for deep learning. Probably too many. TF works at a low level, which I usually like. But with TF, the calling interface just doesn’t feel right to me. The TF interface feels like it was written by researchers with very little experience programming in a non-research environment.


TensorFlow demo code for Iris dataset


TensorFlow demo run.

CNTK also works at a low level, but not quite as low as TF. And for me anyway, CNTK has a much more natural programing interface.

I do like Keras. Keras is a wrapper library that relies on either TF or CNTK (or Theano) for its execution engine. Keras is nice, but it works at a level of abstraction that’s just a bit too high for me.

Here are some code snippets to give you a feel for TF, CNTK, and Keras:

TensorFlow:

classifier = tf.estimator.DNNClassifier(
    feature_columns=my_feature_columns,
    # Two hidden layers of 10 nodes each.
    hidden_units=[10, 10],
    # The model must choose between 3 classes.
    n_classes=3)

# Train the Model.
classifier.train(
    input_fn=lambda:iris_data.train_input_fn(train_x,
    train_y, args.batch_size), steps=args.train_steps))

CNTK:

print("Creating a 4-5-3 NN for Iris dataset ") 
with C.layers.default_options():
  hLayer = C.layers.Dense(hidden_dim,
    activation=C.ops.tanh, name='hidLayer')(X)  
  oLayer = C.layers.Dense(output_dim,
    activation=None, name='outLayer')(hLayer)
nnet = oLayer
model = C.ops.softmax(nnet)

for i in range(0, max_iter):
  curr_batch = rdr.next_minibatch(batch_size,
    input_map=iris_input_map)
  trainer.train_minibatch(curr_batch)

Keras:

model = K.models.Sequential()
model.add(K.layers.Dense(units=8, input_dim=4,
  activation='tanh'))  # hidden layer, 8 nodes
model.add(K.layers.Dense(units=3,
  activation='softmax'))  # output layer, 3 nodes
model.compile(loss='categorical_crossentropy',
  optimizer='sgd', metrics=['accuracy'])

model.fit(train_x, train_y, batch_size=5, epochs=10,
  verbose=0, callbacks=[my_logger])

As I’m writing this post, I’m realizing that unless you have significant experience with one of the three libraries shown above, the code probably looks like gibberish.

The moral of the story: It’s not clear if one deep learning library will come to be the single, dominant library, or if many libraries will exist and see approximately equal usage. For now you have several paths to choose from.



A kinetic sculpture by Karl Hale.

This entry was posted in Machine Learning, Miscellaneous. Bookmark the permalink.