Шаг 78.
Глубокое обучение на Python. Введение в Keras и TensorFlow. Первые шаги с TensorFlow. Полный пример: линейный классификатор на TensorFlow

    На этом шаге мы рассмотрим построение линейного классификатора.

    Вы познакомились с тензорами, переменными и тензорными операциями и узнали, как вычислять градиенты. Оказывается, этого достаточно, чтобы построить любую модель машинного обучения на основе градиентного спуска.

    На собеседовании по машинному обучению вас могут попросить реализовать линейный классификатор с нуля в TensorFlow: очень простая задача, которая помогает отделить кандидатов с минимальным опытом машинного обучения от тех, кто такого опыта не имеет. Давайте вместе выполним это задание и воспользуемся для этого новыми знаниями в TensorFlow.

    Для начала создадим искусственный набор данных, включающий два линейно разделимых класса точек на двумерной плоскости. Для этого сгенерируем каждый класс точек, извлекая их координаты из случайного распределения с определенной ковариационной матрицей и определенным средним значением. Ковариационная матрица описывает форму облака точек, а среднее значение - его положение на плоскости (рисунок 1). Для создания двух облаков точек мы используем одну и ту же ковариационную матрицу, но разные средние значения: как результат, облака точек будут иметь одинаковую форму, но разные местоположения.


Пример 3.13. Создание набора случайных точек двух классов на двумерной плоскости
import numpy as np

num_samples_per_class = 1000
#  Сгенерировать 1000 случайных точек первого класса. 
#  cov=[[1, 0.5],[0.5, 1]] соответствует облаку точек овальной формы, 
#  вытянутому в направлении от левого нижнего к правому верхнему углу
negative_samples = np.random.multivariate_normal( 
    mean=[0, 3], 
    cov=[[1, 0.5],[0.5, 1]], 
    size=num_samples_per_class)

#  Сгенерировать точки второго класса с той же 
#  ковариационной матрицей, но другим средним значением
positive_samples = np.random.multivariate_normal( 
    mean=[3, 0], 
    cov=[[1, 0.5],[0.5, 1]], 
    size=num_samples_per_class)

    Здесь negative_samples и positive_samples - это массивы с формой (1000, 2). Объединим их в один массив с формой (2000, 2).


Пример 3.14. Объединение точек двух классов в один массив с формой (2000, 2)
inputs = np.vstack((negative_samples, positive_samples)).astype(np.float32)

    Теперь сгенерируем соответствующие целевые метки, массив нулей и единиц с формой (2000, 1), где элементы targets[i, 0] равны 0, если input[i] принадлежит классу 0 (и наоборот) .


Пример 3.15. Создание целевых меток (0 или 1)
targets = np.vstack((np.zeros((num_samples_per_class, 1), dtype="float32"),
                     np.ones((num_samples_per_class, 1), dtype="float32")))

    Теперь нарисуем точки с помощью Matplotlib.


Пример 3.16. Вывод классов точек на плоскости (рисунок 1)
import matplotlib.pyplot as plt

plt.scatter(inputs[:, 0], inputs[:, 1], c=targets[:, 0])
plt.show()


Рис.1. Наши искусственные данные: два класса случайных точек на двумерной плоскости

    Теперь создадим линейный классификатор, который научится разделять эти два облака. Линейный классификатор - это аффинное преобразование (prediction = W · input + b), обученное минимизировать квадрат разницы между предсказаниями и целями.

    Как вы убедитесь позднее, данный пример на самом деле гораздо проще, чем двухслойная нейронная сеть, которую мы рассматривали ранее. Но на этот раз у вас достаточно знаний, чтобы понять весь код, каждую его строку.

    На следующем шаге мы закончим изучение этого вопроса.




Предыдущий шаг Содержание Следующий шаг