Некоторое время назад наткнулся на Obama-RNN, очень забавную штуку которая генерит тексты на основе рекуррентных сетей. Основа ее - char-rnn которую создал Andrej Karpathy. Работает это все на основе Torch7, который требует либо MacOS либо Linux. Ради того, чтобы попробовать в деле LSTM и RNN сети, пришлось даже на время отнять макбук жены. Но работать в MacOS мне очень непривычно.

Особых трудностей при портировании не возникло, за исключением того, что я пока плохо понимаю, как работает luarocks и как оформлять пакеты для нескольких платформ. Скорее всего с этим будет связано много рутинной работы так как там директ-линки на репозитарии гитхаба, как это все заточить корректно пока не понятно. И найдется ли на это время.

В рантайме основные функции работают, во всяком случае та же char-rnn отрабатывает на Windows нормально.

Torch7Win

Собранный Torch7 для Windows можно загрузить с OneDrive по адресу http://1drv.ms/1TADqMd. Просто распакуйте архив в любой каталог, например, c:\torch и запустите char-rnn:

git clone https://github.com/dmandreev/char-rnn.git
cd char-rnn
c:\torch\lua.exe train.lua
c:\torch\lua.exe sample.lua cv/lm_lstm_epoch50.00_2.3401.t7 >result.txt

Фан с LSTM сетями

Попробовать char-rnn в деле я решил на давно скачанном образе хабра, скормив ему 3 мегабайта текстов статей. Результат интересный, дальше, если будет время, попробую более глубоко проанализировать тексты и заголовки, так как там есть на чем потренировать регрессию – рейтинг, количество просмотров, количество комментариев. Первые попытки тренировки я делал на MacBook Pro и у меня не хватало памяти, да и терпения ждать, когда он там отпыхтит. Сгенерированные тексты содержали много ошибок. На GTX980 все значительно веселей, несмотря на то что тренировка была на трех слоях . Получаются более гладкие тексты, с уровнем синтаксических ошибок примерно соответствующим «обыкновенным» текстам.

Собираюсь перемечательно создан очень приятно, но при этом сертификаты 
будут пользоваться, а как пользователи в одном иногде подобным, 
так что многим попробовать собственные образ на ваше восприятие. 
Как оказалось, с помощью сбавка поддерживает совместноеужеством. 
Для этого поздно на все слово проблемы о райте или смартфон направлен 
на модуль (и допуская смерты. Интересная тема в том числе выбор 
человеческого картода должны работать на проектировании результатов 
выделена. И такое разрешение дизайна представитель нельзя, он жил в 
это время трафика (кроме СС стандартного посте. Почему не пользуется 
если и пришли о вычислении отложено на доступ к перегоровом пользователя 
Сэт. Тут версию всей сертификации и количество рубили по их возможностям 
по всей конкурентом: тестирование немного общего проблека постройка 
продукта - они могут прибылить, что дальше есть свежий пульта и вы также 
холод по более широко настройки работ (и некоторые производительности 
до начинки. Компания Nokia Nogialer. При этом обычно по большому времени 
вы можете привяток от такового на 60% отражения 
на лишь - при разработке яркости)

Важно то, что LSTM/RNN сети обучаются правильному написанию текстов на уровне последовательности символов. Но в отличие от цепей маркова, нет шаблонности, которая бросается в глаза. Рекуррентной сети все равно, какую информацию будут подавать на вход, постепенно она обучается, как из букв складываются слова, какие буквы следуют за какими, что между словами нужно ставить пробелы и какие слова следуют друг за другом.

Например, можно взять все заголовки хабра для публикаций получивших больше чем 5 тысяч просмотров, и «нагаллюцинировать» новые темы для статей, которые по идее, тоже должны быть популярны. Не хотите написать “Обзор мобильных приложений на PHP”?

Головолома с разрешенными процессойных устройств в Windows 8
Обзор Logitech G подаризает сайт с контроллерами
Как получить на Хабре программиста
Полиценсление на гиткойче и создать игру с помощью CSS-файлов в Mac OS X
Lifuxes: редактируемая финансовый диск
Lensive Reacts Fantoroa Strem 1.0 в WebGL
Разработчики Google Play - зачем он нужен в веде
История и не только> - история в реальном времени
Можно ли пользоваться VCI
Обзор мобильных приложений на PHP
Конструктор на Nokia 800 быстрее, безёлсетны на Хискасте
Получение изображенинения по разумку LomoSh Colorsick? - Часть 1
Русская ОС Tizen - Что нового в космосе
HTML 5 сервисов в мобильник. да стал по снова от использования
Четыре выпускать авторскиев при помощи CSS3 и JavaFX
Персональный jQuery плагин для Android платформы ответов и дизайнеров
О том, как увеличить MySQL на примере под Android
В США из 20-2 из 10 показать на мобильных устройствах
Аналитика на JavaScript (часть 2)
Год собой
А кому ассенблюательным деревьевного предложения
Arduino: приложения с Android на рекламы
Как мы одному используя Mac OS X
Google представил Xperia Z Windows Server 2012 R2 на CSS под Android
Новый дистрибутив на Android за $09
Are.DA-показывают при помощи CSS3
Список оптимизаций и регрессии создать репозилать на косты недового обновления
Подделка на основе Mac API
Код сайтом Сжавых часть подучились
Как я писал свой Google Chrome в CSS
Разработка данных с Django 1.4.5
Пишем простой позволяев заределы удалить процессоры для распознавания лиц
Джон Каму программирования будет российского интера-миру

Заметно отличие заголовков от первого текста, очень много придуманных несуществующих слов. Объём выборки был чуть больше мегабайта, поэтому сеть фантазирует на полную катушку. Понятно, что чем больше данных, тем более качественными будут тексты. Но генерировать можно не только статьи и заголовки, любые наборы текста могут подойти в качестве обучающей выборки, и это позволяет генерировать музыку (в виде текстового представления аккордов), рецепты блюд, и даже программы, ничто не мешает скормить LSTM сети исходники Linux Kernel и получить на выходе нечто очень похожее. Множество результатов таких экспериментов представлено в публикации The Unreasonable Effectiveness of Recurrent Neural Networks.

Известные проблемы

Конечно есть и баги, некорректно работает torch.Timer(), потребовался фикс деалокатора памяти в котором я не совсем уверен, и прочие мелкие шероховатости. Большое опасение вызывает ffi, и из за него падает cudnn модуль, но в остальном расчеты cutorch на GPU работают нормально.

Из интересного – даже в последней Cuda Toolkit 7.5 вылез баг пятилетней давности nvcc о котором писали на форуме Nvidia. При этом не понятно, почему этот баг есть на Windows, но отсутствует на MacOS. Из за этого по condition _MSC_VER из THCDeviceTensor-inl.cuh пришлось убрать определение конструкторов THCDeviceTensor, и воткнуть прямо в определение класса. Причем, у меня сложилось впечатление, что это именно баг nvcc, так как это он генерит файл .ii в котором пропадает template argument для массива в параметрах функции - вместо const IndexT sizes[Dim] получается const IndexT sizes[], и cl не может найти подходящий под шаблон определитель. Квикфикс:

template <typename T,
          int Dim,
          typename IndexT = int,
          template <typename U> class PtrTraits = DefaultPtrTraits>
class THCDeviceTensor {
 public:
  enum { NumDim = Dim };
  typedef T DataType;
  typedef IndexT IndexType;
  typedef typename PtrTraits<T>::PtrType DataPtrType;
  typedef THCDeviceTensor<T, Dim, IndexT, PtrTraits> TensorType;

  /// Default constructor
  __host__ __device__ THCDeviceTensor();

  /// Constructor that calculates strides with no padding
  __host__ __device__ THCDeviceTensor(DataPtrType data,
                                      const IndexT sizes[Dim])
#if defined(_MSC_VER)
                                      : data_(data) {
      thc_static_assert(Dim > 0);

      for (int i = 0; i < Dim; ++i) {
          size_[i] = sizes[i];
      }

      stride_[Dim - 1] = (IndexT) 1;
      for (int i = Dim - 2; i >= 0; --i) {
          stride_[i] = stride_[i + 1] * sizes[i + 1];
      }
  }

#endif
;

  /// Constructor that takes arbitrary size/stride arrays
  __host__ __device__ THCDeviceTensor(DataPtrType data,
                                       const IndexT sizes[Dim],
                                       const IndexT strides[Dim])
#if defined (_MSC_VER)
                                          : data_(data) {
       thc_static_assert(Dim > 0);
        
       for (int i = 0; i < Dim; ++i) {
       	    size_[i] = sizes[i];
            stride_[i] = strides[i];
        }
   }

#endif
;