На этом шаге мы рассмотрим построение линейного классификатора.
Вы познакомились с тензорами, переменными и тензорными операциями и узнали, как вычислять градиенты. Оказывается, этого достаточно, чтобы построить любую модель машинного обучения на основе градиентного спуска.
На собеседовании по машинному обучению вас могут попросить реализовать линейный классификатор с нуля в TensorFlow: очень простая задача, которая помогает отделить кандидатов с минимальным опытом машинного обучения от тех, кто такого опыта не имеет. Давайте вместе выполним это задание и воспользуемся для этого новыми знаниями в TensorFlow.
Для начала создадим искусственный набор данных, включающий два линейно разделимых класса точек на двумерной плоскости. Для этого сгенерируем каждый класс точек, извлекая их координаты из случайного распределения с определенной ковариационной матрицей и определенным средним значением. Ковариационная матрица описывает форму облака точек, а среднее значение - его положение на плоскости (рисунок 1). Для создания двух облаков точек мы используем одну и ту же ковариационную матрицу, но разные средние значения: как результат, облака точек будут иметь одинаковую форму, но разные местоположения.
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).
inputs = np.vstack((negative_samples, positive_samples)).astype(np.float32)
Теперь сгенерируем соответствующие целевые метки, массив нулей и единиц с формой (2000, 1), где элементы targets[i, 0] равны 0, если input[i] принадлежит классу 0 (и наоборот) .
targets = np.vstack((np.zeros((num_samples_per_class, 1), dtype="float32"), np.ones((num_samples_per_class, 1), dtype="float32")))
Теперь нарисуем точки с помощью Matplotlib.
import matplotlib.pyplot as plt plt.scatter(inputs[:, 0], inputs[:, 1], c=targets[:, 0]) plt.show()
Рис.1. Наши искусственные данные: два класса случайных точек на двумерной плоскости
Теперь создадим линейный классификатор, который научится разделять эти два облака. Линейный классификатор - это аффинное преобразование (prediction = W · input + b), обученное минимизировать квадрат разницы между предсказаниями и целями.
Как вы убедитесь позднее, данный пример на самом деле гораздо проще, чем двухслойная нейронная сеть, которую мы рассматривали ранее. Но на этот раз у вас достаточно знаний, чтобы понять весь код, каждую его строку.
На следующем шаге мы закончим изучение этого вопроса.