Release notes

Release 19.9

Release date: Jan 22, 2018
Major Changes in this Release:
New Features and Improvements:
   - Switched the Python API from Boost.Python to pybind11.  This means Python
     users don't need to install Boost anymore, making building dlib's Python API
     much easier.
   - Made the sparse version of svd_fast() use multiple CPU cores.
   - Changed the behavior of imglab's --flip option.  It will now attempt to
     adjust any object part labels so that the flipped dataset has the same
     average part layout as the source dataset. There is also a new --flip-basic 
     option that behaves like the old --flip. However, most people flipping a
     dataset with part annotations will want to use --flip.  For more details

Non-Backwards Compatible Changes:
   - Removed std::auto_ptr from dlib's old (and depreciated) smart pointers. 

Bug fixes:
   - Fixed not working in Python 3.

Release 19.8

Release date: Dec 19, 2017
Major Changes in this Release:
New Features and Improvements:
   - Added a global optimizer, find_max_global(), which is suitable for
     optimizing expensive functions with many local optima.  For example, you
     can use it for hyperparameter optimization.  See model_selection_ex.cpp
     for an example.
   - Updates to the deep learning tooling:
      - Added semantic segmentation examples: dnn_semantic_segmentation_ex.cpp
        and dnn_semantic_segmentation_train_ex.cpp
      - New layers: loss_ranking, loss_epsilon_insensitive, softmax_all, and loss_dot.
      - Made log loss layers more numerically stable.
      - Upgraded the con layer so you can set the number of rows or columns to
        0 in the layer specification. Doing this means "make the filter cover
        the whole input image dimension".  This provides an easy way to make a
        filter sized so it will have one output along that dimension,
        effectively making it like a fully connected layer operating on a row
        or column.
      - Added support for non-scale-invariant MMOD.
      - Added an optional parameter to dnn_trainer::get_net() that allows you
        to call the function without forcing a state flush to disk.
      - Sometimes the loss_mmod layer could experience excessively long runtime
        during early training iterations.  This has been optimized and is now
        much faster.
      - Optimized the tensor's management of GPU memory.  It now uses less memory
        in some cases.  It will also not perform a reallocation if resized to a
        smaller size.  Instead, tensors now behave like std::vector in that
        they just change their nominal size but keep the same memory, only
        reallocating if they are resized to something larger than their
        underlying memory block. This change makes some uses of dlib faster, in
        particular, running networks on a large set of images of differing
        sizes will now run faster since there won't be any GPU reallocations,
        which are notoriously slow.
      - Upgraded the input layer so you can give
        input<std::array<matrix<T>,K>> types as input. Doing
        this will create input tensors with K channels.
   - Added disjoint_subsets_sized
   - Added Python APIs: get_face_chips(), count_steps_without_decrease(),
     count_steps_without_decrease_robust(), and jitter_image().
   - Various improvements to CMake scripts: e.g. improved warning and error
     messages, added USE_NEON_INSTRUCTIONS option.
   - chol() will use a banded Cholesky algorithm for banded matrices, making it
     much faster in these cases.
   - Changed the timing code to use the C++11 high resolution clock and
     atomics. This makes the timing code a lot more precise.

Non-Backwards Compatible Changes:
   - Changed the random_cropper's set_min_object_size() routine to take min box
     dimensions in the same format as the mmod_options object (i.e. two lengths
     measured in pixels). This should make defining random_cropping strategies
     that are consistent with MMOD settings more straightforward since you can
     simply take the mmod_options settings and give them to the random_cropper
     and it will do the right thing.
   - Changed the mean squared loss layers to return a loss that's the MSE, not
     0.5*MSE. The only thing this effects is the logging messages that print
     during training, which were confusing since the reported loss was half the
     size you might naively expect.
   - Changed the outputs of test_regression_function() and cross_validate_regression_trainer().
     These functions now output 4D rather than 2D vectors.  The new output is:
     mean squared error, correlation, mean absolute error, and standard
     deviation of absolute error.  I also made test_regression_function() take
     a non-const reference to the regression function so that DNN objects can
     be tested.
   - Fixed shape_predictor_trainer padding so it behaves as it used to. In
     dlib 19.7 the padding code was changed and accidentally doubled the size
     of the applied padding in some cases. It's not a huge deal either way, but
     this change reverts back to the previous behavior.

Bug fixes:
   - Fixed toMat() not compiling in some cases.
   - Significantly reduced the compile time of the DNN example programs in
     visual studio.
   - Fixed a few image processing functions that weren't using the generic
     image interface.
   - Fixed a bug in the random_cropper where it might crash due to division by
     0 if small images were given as input.
   - Fixed a bug in how the mmod_options automatically determines detection
     window sizes. It would pick a bad size in some cases.
   - Fixed load_image_dataset()'s skip_empty_images() option. It wasn't
     skipping images that only have ignore boxes when you load into mmod_rect
   - Fixed a bug where chinese_whispers(), when called from python, would
     sometimes return a labels array that didn't include labels for all the
   - Fixed a bug in dlib's MS Windows GUI code that was introduced a little
     while back when we switched everything to std::shared_ptr.  This change
     fixes a bug where the program crashes or hangs sometimes during program
   - Fixed error in TIME_THIS() introduced in dlib 19.7. It was printing
     seconds when it said minutes in the output.
   - Adding missing implementation of tabbed_display::selected_tab.
   - Changed the windows signaler and mutex code to use the C++11 thread
     library instead of the old win32 functions. I did this to work around how
     windows unloads dlls. In particular, during dll unload windows will kill
     all threads, THEN it will destruct global objects. So this can lead to
     problems when a global object that owns threads tries to tell them to
     shutdown, since the threads have already vanished.  The new code mitigates
     some of these problems, in particular, there were some cases where
     unloading dlib's python extension would deadlock.  This should now be
   - Fixed compile time errors when either of these macros were enabled:

Release 19.7

Release date: Sep 17, 2017
Major Changes in this Release:
New Features and Improvements:
   - Deep Learning:
      - The CNN+MMOD detector is now a multi-class detector.  In particular,
        the mmod_rect object now has a string label field which you can use to
        label objects, and the loss_mmod_ layer will learn to label objects with
        those labels.  For an example, see:
      - CNN+MMOD detectors are now 2.5x faster.  For instance, this example program now runs at 98fps instead
        of 39fps.  
   - Added a 5 point face landmarking model that is over 10x smaller than the
     68 point model, runs faster, and works with both HOG and CNN generated
     face detections.  It is now the recommended landmarking model to use for 
     face alignment.  render_face_detections() and get_face_chip_details() have been 
     updated to work with both 5 and 68 point models, so the new 5 point model is
     a drop in replacement for the 68 point model.
   - The imglab tool is slightly improved.  It will display box labels with
     higher relative contrast.  You can also now press END or i to ignore boxes
     in imglab. This is useful because it's a much less stressing hand motion
     to hit END that i in most cases.
   - Added overloads of sub_image() that take raw pointers so you can make
     sub_images of anything. 
   - Changed TIME_THIS() to use std::chrono::high_resolution_clock, so now it's
     much higher precision.
   - Exposed Chinese whispers clustering to Python, added face clustering example.

Non-Backwards Compatible Changes:

Bug fixes:
   - Fixed an error in input_rgb_image_pyramid::image_contained_point(). The
     function might erroneously indicate that a point wasn't inside the original
     image when really it was, causing spurious error messages.
   - mmod_options would pick bad window sizes in some corner cases. This has been fixed.
   - Fixed a bug in the extract layer that trigged when a tensor with a
     different number of samples than the tensor used to initialize the network
     was passed through the layer.
   - The loss_per_missed_target parameter of the loss_mmod_ wasn't being used
     exactly right when boxes were auto-ignored.  There weren't any practical
     user facing problems due to this, but it has nevertheless been fixed. 

Release 19.6

Release date: Aug 28, 2017
Major Changes in this Release:
New Features and Improvements:

Non-Backwards Compatible Changes:

Bug fixes:
   - Fix build error in Visual Studio when CUDA is enabled. 

Release 19.5

Release date: Aug 27, 2017
Major Changes in this Release:
New Features and Improvements:
   - Deep Learning
      - Added a python wrapper for using the CNN face detector.
      - Added support for cuDNN v6 and v7.
      - Added a simple tool to convert dlib model files to caffe models.  
        See the tools/convert_dlib_nets_to_caffe folder for details.
      - New DNN layers
         - loss_multiclass_log_per_pixel_
         - loss_multiclass_log_per_pixel_weighted_
         - loss_mean_squared_per_pixel_
         - cont_       (transpose convolution, sometimes called "deconvolution")
         - mult_prev_  (like add_prev_ but multiplies instead of adds)
         - extract_    (sort of like caffe's slice layer)
         - upsample_   (upsamples a tensor using bilinear interpolation)
      - Object Detection
         - Upgraded loss_mmod_ to support objects of varying aspect ratio. This
           changes the API for the mmod_options struct slightly.
         - Relaxed the default non-max suppression parameters used by the
           mmod_options object so that users of the deep learning MMOD tool don't
           get spurious errors about impossibly labeled objects during training.
         - Added missing input validation to loss_mmod_.  Specifically, the loss
           layer now checks if the user is giving truth boxes that can't be detected
           because the non-max suppression settings would prevent them from being
           output at the same time. If this happens then we print a warning message
           and set one of the offending boxes to "ignore".  I also changed all
           the input validation errors to warning messages with auto conversion
           to ignore boxes rather than exceptions.
         - Changed the random_cropper's interface so that instead of talking in
           terms of min and max object height, it's now min and max object size.
           This way, if you have objects that are short and wide (i.e. objects where
           the relevant dimension is width rather than height) you will get sensible
           behavior out of the random cropper.
         - Added options to input_rgb_image_pyramid that let the user set
           create_tiled_pyramid()'s padding parameters. Also changed the default
           outer border padding from 0 to 11. This effects even previously trained
           models. So any model that doesn't explicitly set the outer patting to
           something else will have a padding of 11. This should be a more
           reasonable value for most networks.
         - Added process() and process_batch() to add_loss_layer. These routines
           let you easily pass arguments to any optional parameters of a loss
           layer's to_tensor() routine. For instance, it makes it more convenient to
           set loss_mmod_'s adjust_threshold parameter.
      - Added visit_layers_until_tag()
      - Improved how dnn_trainer synchronizes its state to disk.  It now uses
        two files and alternates between them.  This should be more robust in
        the face of random hardware failure during synchronization than the
        previous synchronization method.
      - Made it so you can set the number of output filters for con_ layers at runtime.
      - The way cuDNN work buffers are managed has been improved, leading to
        less GPU RAM usage.  Therefore, users should not need to call
        set_dnn_prefer_smallest_algorithms() anymore.
      - Added operator<< for random_cropper and dnn_trainer to allow 
        easy logging of training parameters.
      - Made concat_ layer a lot faster.
      - Made the dnn_trainer not forget all the previous loss values it knows
        about when it determines that there have been a lot of steps without
        progress and shrinks the learning rate. Instead, it removes only a
        small amount of the oldest values.   The problem with the old way of
        removing all the loss values in the history was that if you set the
        steps without progress threshold to a really high number you would
        often observe that the last few learning rate values were obviously not
        making progress, however, since all the previous loss values were
        forgotten the trainer needed to fully populate its loss history from
        scratch before it would figure this out.  This new style makes the
        trainer not waste time running this excessive optimization of obviously
        useless mini-batches.  I also changed the default
        get_test_iterations_without_progress_threshold() from 200 to 500.  Now
        that we have a better history management of loss values in the trainer
        it's much more sensible to have a larger value here.
   - Dlib's simd classes will now use ARM NEON instructions.  This makes the
     HOG based object detector faster on mobile devices running ARM processors.
   - Added last_modified() method to dlib::file.  Also, added
     select_oldest_file() and select_newest_file().
   - Added solve_qp_box_constrained_blockdiag()
   - Added an overload of mat() that takes a row stride value.
   - Added cmake scripts and some related tooling that makes it easy to call
     C++ code from java.  See dlib/java/ folder.  
   - MATLAB MEX wrapper API
      - Made the mex wrapper deal with cell arrays that have null elements.
      - Made ctrl+c detection in a mex file work more reliably in newer versions of matlab.
   - Added set_rect_area()
   - Gave test_object_detection_function() an option to set how ignore box
     overlap is tested.
   - Added serialization support for the running_stats_decayed object.
   - Additions to imglab
      - Added --sort and also the ability to propagate boxes from one image to
        the next using dlib::correlation_tracker.
      - Made it so you can remove images by pressing alt+d. 
      - Made is so pressing e in imglab toggles between views of the image
        where the histogram is equalized or unmodified. This way, if you are
        looking at particularly dark or badly contrasted images you can toggle
        this mode and maybe get a better view of what you are labeling.
   - Made the attribute_list of the xml parser a little more friendly by
     allowing you to ask for attributes that don't exist and get a defined
     behavior (an exception being thrown) rather than it being a contract

Non-Backwards Compatible Changes:
   - DNN solver objects are now required to declare operator<<.
   - Broke backwards compatibility with previous dnn_trainer serialization
     format.  The network serialization format has not changed however.  So old
     model files will still load properly.
   - Changed random_cropper interface.
   - Changed the XML format output by net_to_xml(). Specifically, the XML tag
     for affine layers was changed to use the same conventions as other layers
     that support convolutional vs fully connected modes.
   - Dlib's smart pointers have been deprecated and all of dlib's code has been
     changed to use the std:: version of these smart pointers.  The old dlib
     smart pointers are still present, allowing users to explicitly include
     them if needed, but users should migrate to the C++11 standard version of
     these tools. 
   - Changed the functions that transform between input tensor coordinates and
     output tensor coordinates to use dpoint instead of point. This way, we can
     obtain sub-pixel coordinates if we need them.
   - Upgraded loss_mmod_ to support objects of varying aspect ratio. This
     changes the API for the mmod_options struct slightly.

Bug fixes:
   - Made resize_image() and functions that use it like the pyramid objects
     produce better results when run on float and double images. There was
     needless rounding to integers happening in the bilinear interpolation. Now
     if you work with a float image the entire process will run without integer
   - Made the input_tensor_to_output_tensor() and output_tensor_to_input_tensor() 
     coordinate mappings work on networks that contain skip layers.
   - The input_rgb_image_sized is supposed to be convertible to
     input_rgb_image, which it was in all ways except you couldn't deserialize
     directly like you would expect. This has now been fixed.
   - There was a bug in the concat_ layer's backward() method. It was assigning
     the gradient to previous layers instead of adding the gradient, as required
     by the layer interface specification.  Probably no-one has been impacted
     by this bug, but it's still a bug and has been fixed.
   - Changed the random_cropper so that it samples background patches uniformly
     across scales regardless of the input image size. Previously, if you gave
     really large images or really small images it had a bias towards giving only
     large patches or small patches respectively.
   - Fixed name lookup problem for calls to serialize() on network objects.
   - Fixed double delete in tokenizer_kernel_1.
   - Fixed error in pyramid_down<2> that caused the output image to be a
     little funny looking in some cases.
   - Fixed the visit_layers_backwards() and visit_layers_backwards_range()
     routines so they visit layers in the correct order.
   - Made build scripts work on a wider range of platforms and configurations.
   - Worked around global timer cleanup issues that occur on windows when dlib
     is used in a dll in some situations.
   - Fixed various compiler errors in obscure environments.

Release 19.4

Release date: Mar 07, 2017
Major Changes in this Release:
New Features:

Non-Backwards Compatible Changes:
   - CMake 2.8.12 is now required to build dlib (but only if you use CMake).  

Bug fixes:
   - Fixed a slow memory leak that could occur when using cuDNN.


Release 19.3

Release date: Feb 21, 2017
Major Changes in this Release:
New Features:
   - Deep Learning
      - Added a state-of-the-art face recognition tool (99.38% accuracy on the
        LFW benchmark) with C++ and Python example programs.
      - Added these new loss layer types: loss_metric_, loss_mean_squared_, and
      - Added the l2normalize_ computational layer.
      - Added test_one_step() to the dnn_trainer. This allows you to do
        automatic early stopping based on observing the loss on held out data.
      - Made the dnn_trainer automatically reload from the last good state if a
        loss of NaN is encountered.
      - Made alias_tensor usable when it is const.
   - Dlib's simd classes will now use PowerPC VSX instructions.  This makes the
     HOG based object detector faster on PowerPC machines.
   - Added compute_roc_curve()
   - Added find_gap_between_convex_hulls()
   - Added serialization support for std::array.
   - Added running_scalar_covariance_decayed object
   - Added running_stats_decayed object
   - Added min_pointwise() and max_pointwise().
   - Added a 1D clustering routine: segment_number_line().
   - Added Intel MKL FFT bindings.
   - Added matlab_object to the mex wrapper. Now you can have parameters that
     are arbitrary matlab objects.
   - Added support for loading of RGBA JPEG images

Non-Backwards Compatible Changes:
   - Changed the loss layer interface to use two typedefs, output_label_type
     and training_label_type instead of a single label_type. This way, the label
     type used for training can be distinct from the type output by the network.
     This change breaks backwards compatibility with the previous API.

Bug fixes:
   - Fixed compiler warnings and errors on newer compilers.
   - Fixed a bug in the repeat layer that caused it to throw exceptions in some
   - Fixed matlab crashing if an error message from a mex file used the %
     character, since that is interpreted by matlab as part of an eventual
     printf() code.
   - Fixed compile time error in random_subset_selector::swap()
   - Fixed missing implementation of map_input_to_output() and
     map_output_to_input() in the concat_ layer.
   - Made the dnn_trainer's detection and backtracking from situations with
     increasing loss more robust. Now it will never get into a situation where it
     backtracks over and over. Instead, it will only backtrack a few times in a
     row before just letting SGD run unimpeded.

   - Usability improvements to DNN API.
   - Improved C++11 detection, especially on OS X.
   - Made dlib::thread_pool use std::thread and join on the threads in
     thread_pool's destructor. The previous implementation used dlib's global
     thread pooling to allocate threads to dlib::thread_pool, however, this
     sometimes caused annoying behavior when used as part of a MATLAB mex file,
     very occasionally leading to matlab crashes when mex files were unloaded.
     This also means that dlib::thread_pool construction is a little bit slower
     than it used to be.

Release 19.2

Release date: Oct 10, 2016
Major Changes in this Release:
New Features:
   - Updates to the deep learning API:
      - Added tools for making convolutional neural network based object detectors.  See
        dnn_mmod_ex.cpp example program.
      - Added annotation() to tensor so you can associate any object you want with a tensor.
      - Made layer_details() part of the SUBNET interface so that user defined layer
        details objects can access each other. Also added the input_layer() global function
        for accessing the input layer specifically.
      - alias_tensor can now create aliases of const tensors.
      - Added set_all_bn_running_stats_window_sizes().
      - Added visit_layers_backwards(), visit_layers_backwards_range(), and
      - Computational layers can now optionally define map_input_to_output() and
        map_output_to_input() member functions.  If all layers of a network provide these
        functions then the new global functions input_tensor_to_output_tensor() and
        output_tensor_to_input_tensor() can be used to map between the network's input and
        output tensor coordinates.  This is important for fully convolutional object
        detectors since they need to map between the image space and final feature space.
        These new functions are important for tools like the new MMOD detector.
      - Added input_rgb_image_pyramid.
   - Image Processing
      - The imglab command line tool has these new options: --min-object-size, --rmempty,
        --rmlabel, --rm-if-overlaps, and --sort-num-objects.  I also changed the behavior of
        --split so that it simply partitions the data and is an invertible operation.
      - Added mmod_rect
      - Added an overload of load_image_dataset() that outputs directly to mmod_rect
        instead of rectangle.
      - Added image_dataset_file::shrink_big_images(). So now load_image_dataset() can load
        a dataset of high resolution files at a user requested lower resolution.
      - Added box_intersection_over_union().
      - Added create_tiled_pyramid(), image_to_tiled_pyramid(), and tiled_pyramid_to_image().
      - Added random_cropper
   - Upgraded dlib's mex wrapper tooling to enable easy binding of C++ classes to MATLAB
   - Added nearest_rect()
   - Added find_upper_quantile()
   - Added count_steps_without_decrease_robust().
   - Added get_double_in_range() to dlib::rand.

Non-Backwards Compatible Changes:
   - C++11 is now required to use dlib.  
   - Changed pinv() so it interprets its tol argument relative to the largest singular
     value of the input matrix rather than as an absolute tolerance.  This should generally
     improve results, but could change the output in some cases.
   - Renamed the class members of test_box_overlap so they are less confusing.
   - Updates to the deep learning API:
      - Changed the DNN API so that sample_expansion_factor is a runtime variable rather
        than a compile time constant. This also removes it from the input layer interface
        since the DNN core now infers its value at runtime. Therefore, users that define their
        own input layers don't need to specify it anymore.
      - Changed DEFAULT_BATCH_NORM_EPS from 1e-5 to 1e-4.
      - Changed the default batch normalization running stats window from 1000 to 100.

Bug fixes:
   - Made the relational operators constexpr so they don't accidentally cause compilation
     errors when they get pulled into the scope of template metaprogramming expressions.
   - Fixed all/source.cpp not compiling in some instances.
   - CMake scripts now do a better job detecting things like C++11 support, the presence of
     CUDA, and other system specific details that could cause the build to fail if not
     properly configured.
   - Fixed a bug in imglab's --cluster option where it would output xml files with empty
     entries if the input xml file contained unannotated images.
   - Fixed imglab's --cluster option not working with relative paths.

   - Made the thread local variables that hold the cudnn and cublas context objects not
     destruct and recreate themselves when you switch devices.  Instead, they keep a table
     of context objects, for each thread and device, reusing as necessary. This prevents
     churn in the context objects when you are switching back and forth between devices
     inside a single thread, making things run more efficiently for some CUDA based
   - Made the message argument of the DLIB_ASSERT and DLIB_CASSERT macros optional.
   - Made thread_pool and parallel_for propagate exceptions from task threads to calling
     code rather than killing the application if a task thread throws.
   - Changed imglab --resample so that it never changes the aspect ratio of an image.
   - Made the check in dnn_trainer for convergence more robust. Previously, if we
     encountered a bad mini-batch that made the loss value suddenly jump up by a larger than
     normal value it could make the trainer think we converged. Now the test is robust to
     transient spikes in loss value.  Additionally, the dnn_trainer will now check if the
     loss has been increasing before it saves the state to disk. If it detects that the loss
     has been going up then instead of saving to disk it recalls the previously good state.
     This way, if we hit a really bad mini-batch during training which negatively effects
     the model in a significant way, the dnn_trainer will automatically revert back to an
     earlier good state.

Release 19.1

Release date: Aug 13, 2016
Major Changes in this Release:
New Features:
   - Support for cuDNN 5.1
   - dlib::async() and dlib::default_thread_pool().
   - rectangle_transform
   - imglab tool: added --resample, --ignore, --files, and --extract-chips
     command line options.  Also added convert_imglab_paths_to_relative and
     copy_imglab_dataset scripts.
   - Evgeniy Fominov made the shape_predictor trainer multi-threaded and faster.
   - sutr90 contributed support for the CIELab color space.  See the new lab_pixel.

Non-Backwards Compatible Changes:
   - All the cmake utility scripts were moved to dlib/cmake_utils.  
   - Code that #includes the shape_predictor can now only be compiled with
     compilers that support C++11 lambda functions.

Bug fixes:
   - Made CMake scripts work in a wider range of environments. 
   - Fixed compile time errors on various platforms.
   - Fixed bad multi-threading support in the MATLAB mex wrapper.
   - Fixed bug in cuDNN binding that could sometimes cause NaN outputs.
   - Fixed bad convergence testing in DNN tooling for very small datasets.


Release 19.0

Release date: Jun 25, 2016
Major Changes in this Release:
New Features:
   - A deep learning toolkit using CPU and/or GPU hardware.  Some major elements
     of this are:
      - Clean and fully documented C++11 API
      - Clean tutorials: see dnn_introduction_ex.cpp and dnn_introduction2_ex.cpp
      - Uses cuDNN v5.0
      - Multi-GPU support
      - Automatic learning rate adjustment
      - A pretrained 1000 class Imagenet classifier (see dnn_imagenet_ex.cpp)
   - Optimization Tools
      - Added find_optimal_parameters()
      - Added elastic_net class
      - Added the option to use the elastic net regularizer to the OCA solver.
      - Added an option to solve the L2-loss version of the SVM objective function to svm_c_linear_dcd_trainer.
      - Added solve_qp_box_constrained()
   - Image Processing
      - Added random_color_transform, disturb_colors(), and apply_random_color_offset().
      - load_image() now supports loading GIF files.
   - Many improvements to the MATLAB binding API  
      - Automatically link to MATLAB's Intel MKL when used on linux.
      - struct support
      - mex functions can have up to 20 arguments instead of 10.
      - In place operation.  Made column major matrices directly wrap MATLAB
        matrix objects when used inside mex files.  This way, if you use
        matrix_colmajor or fmatrix_colmajor in a mex file it will not do any
        unnecessary copying or transposing.
      - Catch ctrl+c presses in MATLAB console.  Allowing early termination of mex functions.
      - When used inside mex files, DLIB_ASSERTS won't kill the MATLAB process,
        just throw an exception.
      - Made cerr print in MATLAB as a red warning message.
   - load_mnist_dataset()
   - Added a constructor for seeding rand with a time_t.
   - Added subm_clipped()
   - Added unserialize.
   - Added running_gradient

Non-Backwards Compatible Changes:
   - Everything in dlib/matlab/call_matlab.h is now in the dlib namespace.
   - DLIB_TEST() and DLIB_TEST_MSG() macros now require you to terminate them with a ;

Bug fixes:
   - Fixed bug in 10 argument version of call_matlab() and also cleaned up a few
     minor things.
   - and CMake scripts work in a few more contexts.
   - Fixed compiler errors in visual studio 2015.
   - Fixed a bug in gaussian_blur() that caused messed up outputs when big
     sigma values were used on some pixel types.
   - Fixed minor bugs in join_rows() and join_cols(). They didn't work when one
     of the matrices was empty.

   - Made CMake scripts uniformly require CMake version 2.8.4.
   - Faster fHOG feature extraction / face detection
   - CMake scripts now enable C++11 by default
   - Gave array2d and matrix move constructors and move assignment operators.  Matrix
     can also now be created from initializer lists.

Old Release Notes