Мое впечатление о курсе Tensorflow в Стэнфорде: задание 1

Первое задание этого курса охватывает 3 основные проблемы. Первый - это просто заполнение недостающих фрагментов кода для решения простых задач. Второй - реализация модели глубокой нейронной сети, которая дает точность 97% + на наборе данных MNIST. И третий - реализация модели CBOW. Вы можете найти задание здесь.

№1. Проблема 1

Эта часть в первую очередь проверяет ваши базовые знания Tensorflow.

а) Проблема: создайте два случайных 0-мерных тензора x и y любого распределения. Создайте объект TensorFlow, который возвращает x + y, если x ›y, и x - y в противном случае. Подсказка: найдите tf.cond ()

Решение:

Ссылка: tf.cond ()

б) Проблема: создайте два 0-мерных тензора x и y, случайно выбранных из диапазона [-1, 1). Вернуть x + y, если x ‹y, x - y, если x› y, 0 в противном случае. Подсказка: найдите tf.case ().

Решение:

Ссылка: tf.case ()

c) Проблема: создайте тензор x значения [[0, -2, -1], [0, 1, 2]] и y как тензор нулей с одинаковыми форма как x. Возвращает логический тензор, который дает Истину, если x равно y поэлементно. Подсказка: найдите tf.equal ().

Решение:

Ссылка: tf.zeros_like () и tf.equal ()

г) Задача: создайте тензор x значения [29.05088806, 27.61298943, 31.19073486, 29.35532951, 30.97266006, 26.67541885, 38.08450317, 20.74983215, 34.94445419, 34.45999146, 30.061648605327, 36.0.5999146, 29.061648605327, 36.0, 29.061648602327, 36 , 29.51215172, 33.71149445, 28.59134293, 36.05556488, 28.66994858]. Получите индексы элементов в x, значения которых больше 30. Подсказка: используйте tf.where (). Затем извлеките элементы, значения которых больше 30. Совет: используйте tf.gather ().

Решение:

Ссылка: tf.where ()

д) Проблема: создайте диагональный двумерный тензор размером 6 x 6 с диагональными значениями 1, 2,…, 6. Совет: используйте tf.range () и tf. diag ().

Решение:

Ссылка: tf.diag ()

е) Проблема: создайте случайный двумерный тензор размером 10 x 10 из любого распределения. Вычислите его определитель. Подсказка: посмотрите на tf.matrix_determinant ().

Решение:

Ссылка: tf.random_uniform и tf.matrix_determinant () - объяснение определителя матрицы.

ж) Проблема: создайте тензор x со значением [5, 2, 3, 5, 10, 6, 2, 3, 4, 2, 1, 1, 0, 9]. Вернуть уникальные элементы в x. Подсказка: используйте tf.unique (). Имейте в виду, что tf.unique () возвращает кортеж.

Решение:

Ссылка: tf.unique ()

h) Проблема: Создайте два тензора x и y формы 300 из любого нормального распределения, если они принадлежат одному и тому же распределению. Используйте tf.cond () для возврата:

- среднеквадратичная ошибка (x - y), если среднее значение всех элементов в (x - y) отрицательно, или

- сумма абсолютных значений всех элементов тензора (x - y) в противном случае.

Совет: см. функцию потерь Хубера на слайдах лекции 3.

Решение:

№2. Проблема 2

Эта задача состоит из 2 частей: улучшить модель логистической регрессии для достижения точности 97% + для набора данных MNIST или построить новую модель логистической регрессии для набора данных, отличного от MNIST.

Я начал настраивать гиперпараметры этой модели с кода примера. Я также изменил функции активации и сделал другие небольшие улучшения. К сожалению, ни одна из моих попыток не привела к результату 97% + на тестовых данных. Если вам удастся найти соответствующие изменения, я буду рад видеть их в разделе комментариев.

Итак, я поискал модели, которые дают наилучшие результаты, и нашел этот красивый список, который вдохновил меня на попытку создать простую трехслойную сверточную нейронную сеть.

Теперь я объясню полную реализацию ниже. Имейте в виду, что вам это может показаться черным ящиком, но вы получите лучшее понимание сверточных нейронных сетей в моей следующей статье.

Этот код ниже следует за этим примером Tensorflow.

Начнем шаг за шагом:

  • Импортировать библиотеки

numpy и tensorflow должны быть достаточно знакомы, utils используется для загрузки набора данных MNIST. В общем, utils используется для сбора наиболее распространенных функций и операций, используемых в Python.

  • Создайте сверточную нейронную сеть

Он состоит из 2 сверточных слоев, за каждым из которых следует слой максимального пула, а в конце - плотный слой.

Сверточный слой - создает карты характеристик после применения окна фильтра к входным данным (изначально это само изображение).

Уровень объединения - используется для уменьшения размера представления изображения во время обучения.

Плотный слой - это последний слой в модели, который является результатом полного соединения между всеми нейронами в предыдущем слое.

Здесь вы можете найти разницу между этими слоями. Дополнительно здесь - краткое объяснение CNN.

# 0. Наша модельная функция получает входные данные (изображения) и метки в качестве параметров. Кроме того, мы добавляем mode, который используется для Tensorflow Estimator, о чем я расскажу ниже.

№1. Изменить форму ввода

Мы изменяем данные в соответствии с концепцией: [batch_size, image_width, image_height, num_channels]. Поскольку изображения имеют оттенки серого, num_channels равно 1. batch_size имеет значение -1, что означает, что это измерение должно динамически вычисляться на основе количества входных значений.

№2. Первый сверточный слой

Мы используем функцию Tensorflow tf.layers.conv2d (). Позвольте мне быстро объяснить, что означает каждый параметр:

  • input_layer - текущая матрица ввода, это может быть исходное изображение или его реформированная версия.
  • фильтры - после свертки ввода с окном размера (размер_ядра) мы получаем новую матрицу, где его (ширина, высота) = (input_layer.width - kernel_size.width + 1, input_layer.height— kernel_size.height + 1). Фильтры определяют количество матриц указанного выше размера, сложенных вместе.
  • kernel_size - размер окна, которое будет перемещаться по входной матрице.
  • padding - тип заполнения, который нам нужно использовать при достижении краев окна входной матрицы. Более подробную информацию смотрите здесь.
  • активация - применить функцию relu, которая преобразует значение каждого нейрона (если меньше 0, перейти в 0, в противном случае остается прежним)

№3. Первый максимальный уровень пула

Мы используем Tensorflow tf.layers.max_pooling2d для выполнения уровня максимального пула, который уменьшает размер матрицы conv1.

  • pool_size - размер окна, из которого мы выбираем наибольшее значение.
  • strides - количество ячеек, которое нам нужно провести по матрице conv1.

№4. Второй сверточный слой

То же, что и первый сверточный слой, с той лишь разницей, что количество фильтров - 64.

№5. Второй максимальный слой пула

№6. Плотный слой

Это последний уровень в CNN.

  • Сначала мы сглаживаем второй слой максимального пула, преобразовывая его в двумерный массив, имеющий 7 (ширина) * 7 (высота) * 64 (глубина) = 3136 нейронов.
  • Используем типичный плотный слой с размерностью вывода 1024. Подробнее здесь.
  • Применение отсева на плотном слое, которое случайным образом удаляет 40% (коэффициент = 0,4) единиц, чтобы предотвратить переоснащение.
  • В итоге мы получаем последний плотный слой с 10 единицами - количеством разных цифр от 0 до 9.
  • Используйте tf.argmax для получения классов.
  • Нормализуйте логиты, чтобы они находились в диапазоне (0, 1).

№7. Потери и оптимизатор

Давайте рассмотрим функцию потерь:

  • Если мы находимся в режиме прогнозирования, просто верните оценщик с прогнозом (см. Ниже объяснение оценщика TF).
  • Если мы находимся в режиме обучения, создайте onehot_labels на основе ожидаемых значений модели. Понять, как происходит это преобразование, можно здесь.
  • Наконец, мы вычисляем функцию потерь, используя softmax_cross_entropy с ожидаемыми значениями в виде onehot_labels и прогнозируемыми значениями в виде логитов. Если название softmax_cross_entropy звучит для вас неоднозначно, взгляните на этот ответ Quora о разнице между softmax (тип функции активации) и cross_entropy (функция потерь).

Теперь посмотрим на оптимизатор:

Он используется для обновления весов в направлении, которое минимизирует функцию потерь. Global_step предназначен только для отслеживания количества пакетов.

  • Мы выполняем описанные выше действия только в режиме обучения.
  • В качестве оптимизатора мы используем обычный оптимизатор градиентного спуска со скоростью обучения 0,001. Вот красивый список со всеми отличительными оптимизаторами градиентов.
  • Наконец, мы минимизируем функцию потерь.

В случае режима оценки мы просто возвращаем, как часто метки соответствуют прогнозам, используя tf.metric.accuracy.

Основная цель функции потерь и оптимизатора - настроить веса нашей сети так, чтобы ошибка между нашими предсказанными значениями (логиты) а фактические результаты (метки) сведены к минимуму, а прогноз максимально приближен к истине.

№8. Оценщик тензорного потока

API-интерфейс Tensorflow высокого уровня, который помогает обучать, оценивать и тестировать вашу модель. Подробнее об этом вы можете прочитать в документации. Ниже я объясню, как наша модель использует этот Оценщик:

  • Один из типов использования: tf.estimator.ModeKeys, который может быть TRAIN, EVAL, PREDICT и определяет текущий режим.
  • Другой тип: tf.estimator.EstimatorSpec, который предоставляет информацию о текущем состоянии модели основному объекту оценщика.
  • Вы также можете увидеть создание основного объекта Оценщика с помощью tf.estimator.Estimator, который принимает представление модели.
  • Наконец, функция tf.estimator.inputs.numpy_input_fn дает представление данных и, используя .train и .evaluate, мы получаем результаты нашей модели.

№3. Проблема 3

Эта задача состоит из 3 частей, наиболее важной из которых является 3c, которая просит вас реализовать модель CBOW, настроив предоставленный код для skip-граммы. В этой статье я только покажу, как реализовать 3c. Если у вас возникли трудности с выполнением 3a и 3b, оставьте комментарий внизу, и мы сможем обсудить это.

Мы будем модифицировать код скип-граммы, изменив следующие функции:

  • _create_embedding (строка 54):

Из скип-грамма:

Из CBOW:

  • _create_loss (строка 64):

Из скип-грамма:

Из CBOW:

По любым вопросам, касающимся изменений в коде, оставляйте комментарии ниже или пишите мне по электронной почте: simeon dot kostadinoff at gmail dot com.

Спасибо за чтение. Если вам понравилась статья, хлопните в ладоши 👏. Надеюсь у тебя будет отличный день!