Exemple #1
0
def softmax_with_cross_entropy(preds, target_index):
    """
    Computes softmax and cross-entropy loss for model predictions,
    including the gradient

    Arguments:
      preds: np array, shape is either (N) or (batch_size, N) -
        classifier output
      target_index: np array of int, shape is (1) or (batch_size) -
        index of the true class for given sample(s)

    Returns:
      loss, single value - cross-entropy loss
      d_preds, np array same shape as predictions - gradient of predictions by loss value
    """
    # TODO_: Copy from the previous assignment
    # raise Exception("Not implemented!")
    preds = preds.copy()

    probs = softmax(preds)

    loss = cross_entropy_loss(probs, target_index).mean()

    mask = np.zeros_like(preds)
    mask[np.arange(len(mask)), target_index] = 1
    # mask[target_index] = 1

    d_preds = - (mask - softmax(preds)) / mask.shape[0]

    return loss, d_preds
Exemple #2
0
# В общем виде cross-entropy определена следующим образом:
#
# $$
# H(p,q) = -\displaystyle\sum_x p(x)\,\log q(x).
# $$
#
# где $x$ - все классы, $p(x)$ - истинная вероятность принадлежности сэмпла классу $x$, а $q(x)$ - вероятность принадлежности классу $x$, предсказанная моделью.
# В нашем случае сэмпл принадлежит только одному классу, индекс которого передается функции. Для него $p(x)$ равна 1, а для остальных классов - 0.
#
# Это позволяет реализовать функцию проще!

#%%
from linear_classifer import cross_entropy_loss

probs = softmax(np.array([[-5, 0, 5]], ))
cross_entropy_loss(probs, np.array([1]))

#%% [markdown]
# После того как мы реализовали сами функции, мы можем реализовать градиент.
#
# Оказывается, что вычисление градиента становится гораздо проще, если объединить эти функции в одну, которая сначала вычисляет вероятности через softmax, а потом использует их для вычисления функции ошибки через cross-entropy loss.
#
# Эта функция `softmax_with_cross_entropy` будет возвращает и значение ошибки, и градиент по входным параметрам. Мы проверим корректность реализации с помощью `check_gradient`.

#%%
from linear_classifer import softmax_with_cross_entropy

loss, grad = softmax_with_cross_entropy(np.array([[1, 0, 0]]), np.array([1]))

print(loss, grad)
check_gradient(lambda x: softmax_with_cross_entropy(x, np.array([1])),
Exemple #3
0

def array_sum(x):
    assert x.shape == (2, ), x.shape
    return np.sum(x), np.ones_like(x)


check_gradient(array_sum, np.array([3.0, 2.0]))


def array_2d_sum(x):
    assert x.shape == (2, 2)
    return np.sum(x), np.ones_like(x)


check_gradient(array_2d_sum, np.array([[3.0, 2.0], [1.0, 0.0]]))

# TODO Implement softmax and cross-entropy for single sample
probs = linear_classifer.softmax(np.array([-10, 0, 10]))

# Make sure it works for big numbers too!
probs = linear_classifer.softmax(np.array([1000, 0, 0]))
assert np.isclose(probs[0], 1.0)

# My test batch softmax
probs = linear_classifer.softmax(
    np.array([[-10, 0, 10], [30, 4, 5], [2, 6, 8]]))

probs = linear_classifer.softmax(np.array([-5, 0, 5]))
linear_classifer.cross_entropy_loss(probs, 1)