Мы знаем, что линейная регрессия обычно используется для решения регрессионных задач, таких как прогнозирование цен на жилье, прогнозирование температуры и т. д. Фактически, с помощью таких методов, как Softmax, мы также можем использовать линейную регрессию для решения задач множественной классификации. Softmax представляет собой преобразование выходного слоя в структуру сети.Схема выглядит следующим образом:
Технические детали Софтмакс
На приведенном выше рисунке x1, x2 и x3 — это входные слои, которые проходят через две модели линейной регрессии для получения y1 и y2 соответственно:
Затем введите y1 и y2 в модуль Softmax и выведите y1 'и y2'. Результат после обработки Softmax представляет собой дискретное распределение вероятностей, то есть y1 '+ y2' = 1. Таким образом, мы можем использовать y1' и y2' для представления предсказанных вероятностей различных классов.
Конкретные детали Softmax показаны на следующем рисунке:
- Во-первых, выходной результат обрабатывается в степени e, чтобы получить,
- Сложите результаты шага 1: сумма = z1 + z2
- Наконец, разделите результат шага 1 на сумму, чтобы получить,
Поскольку результат обрабатывается в степени e, Softmax будет усиливать большие числа, что приведет к большей вероятности получения больших результатов, поэтому Softmax называется Softmax, а не max.
Функция потерь для классификации Softmax
Классификация Softmax использует функцию потерь перекрестной энтропии (Cross Entropy).Если вы внимательно посмотрите, функция потерь перекрестной энтропии на самом деле является логарифмическим правдоподобием (см.Глубокое понимание логистической регрессииarticle), их цель — максимизировать прогнозируемое значение правильной классификации.
На приведенном выше рисунке y1', y2' и y3' — прогнозируемые вероятности различных классификаций, которые являются выходными результатами Softmax; y1, y2 и y3 — реальные данные классификации. В задаче классификации только одна из этих трех числа равно 1, два других равны 0, поэтому y1, y2 и y3 также являются распределением вероятностей.
Тогда наша задача машинного обучения становится такой: предсказать распределение вероятностейПостоянное приближение к истинному распределению вероятностейпроблема с оптимизацией. Мы используем перекрестную энтропию для измерения разницы между двумя распределениями вероятностей. Чем меньше перекрестная энтропия, тем ближе два распределения. Перекрестная энтропия выражается следующим образом:
В приведенной выше формуле q указывает, что существует q категорий,— вероятность для j-го класса. Сложение перекрестной энтропии всех выборок и есть функция потерь, которую мы хотим:
Как я только что сказал, перекрестная энтропия эквивалентна логарифмическому правдоподобию, и вы можете понять это с точки зрения логарифмического правдоподобия. Кроме того, вы также можете понять с точки зрения теории информации:
В теории информации энтропияиспользуется для описания ожидаемого количества информации, содержащейся в системе, гдеявляется самоинформацией, указывающей на то, что вероятностьКоличество информации, генерируемой при возникновении события, самоинформацию можно понимать как событие с небольшой вероятностью, которое будет генерировать большой объем информации, и, наоборот, событие с большой вероятностью будет генерировать небольшой объем информации.
в то время как перекрестная энтропияОписывает: усилия, необходимые для удаления информации из системы, а при ее распространениииПри равенстве требуемое усилие минимально —Из-за этого машинное обучение, достигнув минимума, использует кросс-энтропию в качестве функции потерь.
Для более подробного объяснения см.эта статья.
Внедрение Softmax с нуля
Теперь мы используем TF2.0 для реализации Softmax с нуля, шаги следующие:
- Определение мультиклассовой модели Softmax
- Определите функцию потерь
- обучать, оценивать модель
Определение мультиклассовой модели Softmax
Модель линейной регрессии Softmax в основном делает две вещи:
1. Сделайте матричное умножение между матрицей входных данных и матрицей параметров.Количество строк входных данных - это количество выборок n, а содержимое каждой строки - это функция каждой выборки.Если количество функций равно d , форма входных данныхn*d
, обучать несколько фрагментов данных одновременно, чтобы достичь цели пакетного расчета; размерность матрицы параметровd*q
, d по-прежнему является количеством признаков, а q — количеством классификаций, поэтому результат умножения равенn*q
, что означает выход каждой выборки из n выборок по разным классификациям;
Во-вторых, выполните обработку Softmax результатов первого шага, чтобы получить результаты прогнозирования каждой выборки в разных категориях.
def net(X):
'''
一层线性回归网络,输出 softmax 后的多分类结果
Args:
- X: n 条样本,每条样本有 d 个维度,即 n*d 维矩阵
- W: 全局参数,d*q 维矩阵,q 表示分类数
- b: bias,1*q 维向量
Return:
- softmax 后的多分类结果
'''
return softmax(tf.matmul(X, W) + b)
def softmax(y):
'''
对 n 个样本,每个样本有 q 种分类的数据做softmax
Args:
- y: n*q 维的矩阵
Return:
- n*q 维的 softmax 后的矩阵
Example:
>>> y = np.array([[0.1,0.2,0.8],[0.8,0.2,0.1]])
>>> softmax(y)
<tf.Tensor: shape=(2, 3), dtype=float64, numpy=
array([[0.24278187, 0.26831547, 0.48890266],
[0.48890266, 0.26831547, 0.24278187]])>
'''
return tf.exp(y) / tf.reduce_sum(tf.exp(y), axis=1, keepdims=True)
Определите функцию потерь
Обратите внимание на формулу функции кросс-энтропийных потерь, чтобы реализовать ее, вы должны сначала получить прогнозируемую вероятность, соответствующую правильной классификации:
Здесь горячее кодирование используется для преобразования целевого вектора в ту же матричную форму, что и прогнозируемый результат.Например, прогнозируемый результатn*q
(n означает прогнозирование n выборок за раз, q означает количество классификаций), тогда горячее кодирование также преобразует целевой вектор вn*q
матрица;
Затем выполните операцию И над матрицей предсказания и целевой матрицей.boolean_mask
Прогнозируемое значение, соответствующее правильной классификации, может быть извлечено;
Наконец, вычисляется прогнозируемое значение-log
, а затем sum — потери этой партии образцов, код выглядит следующим образом:
def cross_entropy(y, y_hat):
'''
交叉熵损失函数
Args:
- y: n 条样本的目标值,n*1 向量
- y_hat: n 条样本的预测分布(softmax输出结果), n*q 矩阵
Return:
n 个样本的 -log(y_hat) 的和
Examples:
>>> y = np.array([[2],[1]])
>>> y_hat = np.array([[0.1,0.2,0.2],[0.3,0.9,0.2]])
>>> cross_entropy(y, y_hat)
<tf.Tensor: shape=(), dtype=float64, numpy=1.7147984280919266>
'''
y_obs = tf.one_hot(y, depth=y_hat.shape[-1])
y_obs = tf.reshape(y_obs, y_hat.shape)
y_hat = tf.boolean_mask(y_hat, y_obs)
return tf.reduce_sum(-tf.math.log(y_hat))
Модель оценки
На этот раз мы используем показатель точности (accuracy) для оценки эффекта модели, показатель точности означает долю правильных прогнозов.
При оценке модели сначала сделайте прогноз для данных, а затем сравните результат прогноза (классификацию с наибольшим значением вероятности) с правильной классификацией, чтобы подсчитать количество правильных прогнозов. используется здесьtf.argmax
функция, что означает, что среди нескольких категорий предсказания наибольшее значение берется в качестве результата предсказания:
def accuracy(x, y, num_inputs, batch_size):
'''
求数据集的准确率
Args:
- x: 数据集的特征
- y: 数据集的目标值,n*1 维矩阵
- num_inputs: 特征维度(输入层个数)
- batch_size: 每次预测的批次
'''
test_iter = tf.data.Dataset.from_tensor_slices((x, y)).batch(batch_size)
acc, n = 0, 0
for X, y in test_iter:
X = tf.reshape(X, (-1, num_inputs))
y = tf.cast(y, dtype=tf.int64)
acc += np.sum(tf.argmax(net(X), axis=1) == y)
n += y.shape[0]
return acc/n
тренироваться
Выше приведены общие методы, необходимые для обучения модели, прогнозирования и оценки. Далее мы можем обучить модель. На этот раз мы используем набор данных fashion_mnist, в котором каждый образец представляет собой28*28
Пиксельное изображение, метка целевого значения — это номер категории, к которой принадлежит это изображение. Всего в наборе данных 10 категорий, как показано ниже:
Наша задача — прочитать такую картинку и предсказать, к какой категории она относится. Входными данными для модели может быть значение каждого пикселя изображения, поскольку28*28=784
пикселей, а диапазон значений каждого пикселя составляет 0-255, тогда количество узлов во входном слое нашей модели равно 784; поскольку в наборе данных всего 10 категорий, форма параметра модели W имеет вид784*10
размерная матрица, форма смещения10*1
, а количество узлов в выходном слое также равно 10.
После выяснения параметров, остальное - итерация модели, эта часть и предыдущаяЛинейная регрессияКод обучения примерно такой же, код выглядит следующим образом:
import tensorflow as tf
from tensorflow import keras
import numpy as np
import time
import sys
from tensorflow.keras.datasets import fashion_mnist
def train(W, b, lr, num_inputs):
(x_train, y_train), (x_test, y_test) = fashion_mnist.load_data()
# 数据归一化
x_train = tf.cast(x_train, tf.float32) / 255
x_test = tf.cast(x_test, tf.float32) / 255
batch_size = 256
num_epochs = 5
for i in range(num_epochs):
# 小批量迭代
train_iter = tf.data.Dataset.from_tensor_slices((x_train, y_train)).batch(batch_size)
train_acc_sum, loss_sum, n = 0, 0, 0
for X, y in train_iter:
X = tf.reshape(X, (-1, num_inputs))
y = tf.reshape(y, (-1, 1))
# 计算loss和梯度
with tf.GradientTape() as tape:
l = cross_entropy(y, net(X))
grads = tape.gradient(l, [W, b])
# 根据梯度调整参数
W.assign_sub(lr * grads[0])
b.assign_sub(lr * grads[1])
loss_sum += l.numpy() # 累加loss
n += y.shape[0] #累加训练样本个数
print("epoch %s, loss %s, train accuracy %s, test accuracy %s"
% (i+1, loss_sum/n,
accuracy(x_train, y_train, num_inputs, batch_size),
accuracy(x_test, y_test, num_inputs, batch_size)))
num_inputs = 784
num_outputs = 10
lr = 0.001
# 初始化模型参数
W = tf.Variable(tf.random.normal(shape=(num_inputs, num_outputs),
mean=0, stddev=0.01, dtype=tf.float32))
b = tf.Variable(tf.zeros(num_outputs, dtype=tf.float32))
train(W, b, lr, num_inputs)
Ниже приведены результаты обучения.Видно, что использование простой модели, такой как линейная регрессия, также может обеспечить точность 0,85 для задачи классификации изображений fashion_mnist.
epoch 1, loss 0.8956155544281006, train accuracy 0.82518, test accuracy 0.8144
epoch 2, loss 0.6048591234842936, train accuracy 0.83978, test accuracy 0.8272
epoch 3, loss 0.5516327695210774, train accuracy 0.84506, test accuracy 0.8306
epoch 4, loss 0.5295544961929322, train accuracy 0.84906, test accuracy 0.8343
epoch 5, loss 0.5141636388142904, train accuracy 0.85125, test accuracy 0.8348
простая реализация
Как обычно, давайте также рассмотрим простую реализацию Softmax:
# 加载数据集
(x_train, y_train), (x_test, y_test) = fashion_mnist.load_data()
x_train = x_train / 255
x_test = x_test / 255
# 配置模型
model = keras.Sequential([
keras.layers.Flatten(input_shape=(28, 28)), # 输入层
keras.layers.Dense(10, activation=tf.nn.softmax) # 输出层,激活函数使用的是 softmax
])
# 配置交叉熵损失函数
loss = 'sparse_categorical_crossentropy'
# 配置 SGD,学习率为 0.1
optimizer = tf.keras.optimizers.SGD(0.1)
model.compile(optimizer=optimizer,
loss = loss,
metrics=['accuracy']) # 使用准确率来评估模型
model.fit(x_train, y_train, epochs=5, batch_size=256)
Его по-прежнему нужно только настроить, и вам не нужно писать строчку логического кода.
резюме
В этой статье мы научились использовать линейную регрессию и Softmax для реализации модели с несколькими классами и фактически использовали набор данных fashion_mnist для проведения экспериментов и получили хорошую точность 0,85.В этой статье есть две детали, которые необходимо быть освоенным
- Детали реализации Softmax
- Принцип функции кросс-энтропийных потерь
Ссылаться на:
- Практическое глубокое обучение — регрессия Softmax (zh.gluon.ai/)
- Практическое глубокое обучение, версия TF2.0 — регрессия Softmax
- Как понять кросс-энтропию и относительную энтропию
Статьи по Теме: