Tensorflow стал одним из наиболее адаптированных фреймворков для проектов глубоких нейронных сетей. В настоящее время Tensorflow предоставляет богатые API-интерфейсы на Python. Используя Keras, очень легко построить и обучить глубокую нейронную сеть. Его API-интерфейсы C ++ сейчас гораздо менее зрелы. Построить граф Tensorflow DNN с помощью C ++ очень сложно. Здесь я описываю некоторые из моих экспериментальных кодов, которые создают и обучают образец нейронной сети для классификации светофора из изображений в среде моделирования. Цель состоит в том, чтобы в будущем предоставить API-интерфейсы Keras, подобные C ++. Код можно найти в моем github.

Пример сетевой архитектуры

Глубокая нейронная сеть в нашем примере - это сеть CNN, разработанная Nvidia для оценки угла вождения. Мы обучим эту сеть классификации изображений светофора. Ниже показана сетевая архитектура.

Построить и обучить модель

Класс модели в tfplusplus.h предоставляет простой API для создания последовательной DNN, которая позволяет пользователю интуитивно добавлять слои NN.

template <typename T, typename... args>
void build_seq(const T& op, const args&... others);

Ниже приведен код, который создает образец нейронной сети в main.cc:

model m({BATCH_SIZE, 96, 128, 3});
m.build_seq (
     conv2d({5, 5, 24}, {1, 2, 2, 1}, "SAME"),
     elu(),
     maxpool({1, 2, 2, 1}, {1, 1, 1, 1}, "SAME"),
     conv2d({5, 5, 36}, {1, 2, 2, 1}, "SAME"),
     elu(),
     maxpool({1, 2, 2, 1}, {1, 1, 1, 1}, "SAME"),
     conv2d({5, 5, 48}, {1, 2, 2, 1}, "SAME"),
     elu(),
     maxpool({1, 2, 2, 1}, {1, 1, 1, 1}, "SAME"),
     conv2d({3, 3, 64}, {1, 1, 1, 1}, "SAME"),
     elu(),
     maxpool({1, 2, 2, 1}, {1, 1, 1, 1}, "SAME"),
     conv2d({3, 3, 64}, {1, 1, 1, 1}, "SAME"),
     elu(),
     flatten(), 
     dense2d(1164, activation::Elu),
     dense2d(100, activation::Elu),
     dense2d(50, activation::Non),
     dense2d(10, activation::Non),
     dense2d(3, activation::Non),
     softmax()
   );

После построения графика нам нужно инициализировать переменные перед обучением. API инициализации в классе модели инициализирует все переменные в модели, добавляет операции градиента и применяет указанный оптимизатор:

m.initialize(optimizer::Adam);

API train в классе модели обучает пакет данных. Следующий код показывает, как тренироваться для нескольких эпох. Этот API, вероятно, следует реализовать для обучения нескольких эпох, как это делает Keras fit _ generator.

for(int i = 0; i < EPOCHS; i++) {
  std::cout << "EPOCHS " << i << " start..." << std::endl;
  std::shuffle(tldata.begin(), tldata.begin()+train_num, g); 
  float loss = 0.0, err = 0.0, accu = 0.0;
  for(int k = 0; k < bnum; k++) {
    std::vector<Tensor> outputs;
    int bsize = BATCH_SIZE;
    int start = k*BATCH_SIZE;
    if(start + bsize > train_num) {
      bsize = train_num - start;
    }
    GetBatch(bsize, start, tldata, outputs);
    const Tensor& images = outputs[0];
    const Tensor& labels = outputs[1];
    auto rec = m.train(images, labels);
    loss += rec[0];   
    err  += rec[1];
    accu += rec[2];
  }
  loss /= bnum;
  err  /= bnum;
  accu /= bnum;
  std::cout << "training loss for epoch " << i << " is " << loss;
  std::cout << " cost " << err;
  std::cout << " accuracy " << accu << std::endl;
}

Сборка и запуск

Чтобы скомпилировать код, вам сначала нужно создать библиотеку C ++ Tensorflow. Этот учебник описывает шаги по созданию библиотеки C ++, которую вы можете связать и построить приложение Tensorflow C ++ с GCC. Команда для создания примера кода:

g++ -I/usr/local/include -L/usr/local/lib -g -std=c++14 model.cc -ltensorflow_cc -ltensorflow_framework -lstdc++fs

Результат

После 160 эпох обучения точность постепенно приближается к 92%.

EPOCHS 0 start...
training loss for epoch 0 is 1.6298 cost 0.27303 accuracy 0.397382
EPOCHS 1 start...
training loss for epoch 1 is 0.730628 cost 0.26032 accuracy 0.401182
EPOCHS 2 start...
training loss for epoch 2 is 0.455526 cost 0.240752 accuracy 0.402872
EPOCHS 3 start...
training loss for epoch 3 is 0.354437 cost 0.246685 accuracy 0.401182
EPOCHS 4 start...
training loss for epoch 4 is 0.297292 cost 0.239769 accuracy 0.401182
EPOCHS 5 start...
training loss for epoch 5 is 0.280813 cost 0.248006 accuracy 0.403294
EPOCHS 6 start...
training loss for epoch 6 is 0.257736 cost 0.237312 accuracy 0.402449
EPOCHS 7 start...
...
EPOCHS 80 start...
training loss for epoch 80 is 0.0185297 cost 0.00611639 accuracy 0.848395
EPOCHS 81 start...
training loss for epoch 81 is 0.0198371 cost 0.00765664 accuracy 0.841639
EPOCHS 82 start...
training loss for epoch 82 is 0.0211765 cost 0.00902148 accuracy 0.839105
EPOCHS 83 start...
training loss for epoch 83 is 0.0241919 cost 0.0117377 accuracy 0.827703
EPOCHS 84 start...
training loss for epoch 84 is 0.0250288 cost 0.0121114 accuracy 0.86951
EPOCHS 85 start...
training loss for epoch 85 is 0.0291566 cost 0.0159336 accuracy 0.852196
EPOCHS 86 start...
training loss for epoch 86 is 0.0283943 cost 0.0145831 accuracy 0.856841
EPOCHS 87 start...
training loss for epoch 87 is 0.0214014 cost 0.00760166 accuracy 0.887669
...
EPOCHS 152 start...
training loss for epoch 152 is 0.00992104 cost 0.00213582 accuracy 0.906672
EPOCHS 153 start...
training loss for epoch 153 is 0.0123421 cost 0.00472957 accuracy 0.920186
EPOCHS 154 start...
training loss for epoch 154 is 0.0106575 cost 0.00296814 accuracy 0.931588
EPOCHS 155 start...
training loss for epoch 155 is 0.00905419 cost 0.00153432 accuracy 0.927365
EPOCHS 156 start...
training loss for epoch 156 is 0.00870481 cost 0.00141313 accuracy 0.92652
EPOCHS 157 start...
training loss for epoch 157 is 0.00854244 cost 0.00144911 accuracy 0.928632
EPOCHS 158 start...
training loss for epoch 158 is 0.00824191 cost 0.00133372 accuracy 0.928209
EPOCHS 159 start...
training loss for epoch 159 is 0.00809524 cost 0.00135928 accuracy 0.928209
EPOCHS 160 start...
training loss for epoch 160 is 0.00796224 cost 0.00139161 accuracy 0.925253

Это намного хуже, чем та же модель, построенная с использованием Keras, которая сходится к 99% точности проверки после 20 эпох. Частично причина, вероятно, связана с некоторыми операциями, используемыми в модели Keras, которые пока недоступны в C ++. Как инициализация и выпадение xavier.

Заключение

Мы демонстрируем, что API-интерфейсы Tensorlfow C ++ можно использовать для построения и обучения нейронной сети DNN, хотя производительность несопоставима с реализацией Keras. Для созревания API C ++ потребуется некоторое время. Моя цель - предоставить Keras, как C ++ API, чтобы упростить сборку и обучение модели Tensorflow C ++.