# Copyright 2019 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Tests SoftmaxRegression class.

Generates some fake data and tries to overfit the data with SoftmaxRegression.
"""
import unittest

from edgetpu.learn.backprop.softmax_regression import SoftmaxRegression
import numpy as np


def generate_fake_data(class_sizes, means, cov_mats):
  """Generates fake data for training and testing.

  Examples from same class is drawn from the same MultiVariate Normal (MVN)
  distribution.

   # classes = len(class_sizes) = len(means) = len(cov_mats)
   dim of MVN = cov_mats[0].shape[0]

  Args:
    class_sizes: list of ints, number of examples to draw from each class.
    means: list of list of floats, mean value of each MVN distribution.
    cov_mats: list of ndarray, each element is a k by k ndarray, which
      represents the covariance matrix in MVN distribution, k is the dimension
      of MVN distribution.

  Returns:
    a tuple of data and labels. data and labels are shuffled.
  """
  # Some sanity checks
  assert len(class_sizes) == len(means)
  assert len(class_sizes) == len(cov_mats)

  num_data = np.sum(class_sizes)
  feature_dim = len(means[0])
  data = np.empty((num_data, feature_dim))
  labels = np.empty((num_data), dtype=int)

  start_idx = 0
  class_idx = 0
  for size, mean, cov_mat in zip(class_sizes, means, cov_mats):
    data[start_idx:start_idx + size] = np.random.multivariate_normal(
        mean, cov_mat, size)
    labels[start_idx:start_idx + size] = np.ones(size, dtype=int) * class_idx
    start_idx += size
    class_idx += 1

  perm = np.random.permutation(data.shape[0])
  data = data[perm, :]
  labels = labels[perm]

  return data, labels


class SoftmaxRegressionTest(unittest.TestCase):

  def testSoftmaxRegressionLinearSeparableData(self):
    # Fake data is generated from 3 MVN distributions, these MVN distributionss
    # are tuned to be well-separated, such that it can be separated by
    # SoftmaxRegression model (which is a linear classifier).
    num_train = 200
    num_val = 30
    # Let's distribute data evenly among different classes.
    num_classes = 3
    class_sizes = ((num_train + num_val) // num_classes) * np.ones(
        num_classes, dtype=int)
    class_sizes[-1] = (num_train + num_val) - np.sum(class_sizes[0:-1])

    # 3 is chosen, such that each pair of mean is over 6 `sigma` distance
    # apart. Which makes classes harder to `touch` each other.
    # https://en.wikipedia.org/wiki/68%E2%80%9395%E2%80%9399.7_rule
    means = np.array([[1, 1], [-1, -1], [1, -1]]) * 3
    feature_dim = len(means[0])
    cov_mats = [np.eye(feature_dim)] * num_classes

    model = SoftmaxRegression(feature_dim, num_classes)
    np.random.seed(12345)
    all_data, all_labels = generate_fake_data(class_sizes, means, cov_mats)

    dataset = {}
    dataset['data_train'] = all_data[0:num_train]
    dataset['labels_train'] = all_labels[0:num_train]
    dataset['data_val'] = all_data[num_train:]
    dataset['labels_val'] = all_labels[num_train:]
    # Train with SGD.
    num_iter = 20
    learning_rate = 0.01
    model.train_with_sgd(
        dataset, num_iter, learning_rate, batch_size=100, print_every=5)
    self.assertGreater(
        model.get_accuracy(dataset['data_train'], dataset['labels_train']),
        0.99)

  def testSoftmaxRegressionLinearNonSeparableData(self):
    # Fake data is generated from 3 MVN distributions, these MVN distributions
    # are NOT well-separated.
    num_train = 200
    num_val = 30
    # Let's distribute data evenly among different classes.
    num_classes = 3
    class_sizes = ((num_train + num_val) // num_classes) * np.ones(
        num_classes, dtype=int)
    class_sizes[-1] = (num_train + num_val) - np.sum(class_sizes[0:-1])

    means = np.array([[1, 1], [-1, -1], [1, -1]])
    feature_dim = len(means[0])
    cov_mats = [np.eye(feature_dim)] * num_classes

    model = SoftmaxRegression(feature_dim, num_classes)
    np.random.seed(54321)
    all_data, all_labels = generate_fake_data(class_sizes, means, cov_mats)

    dataset = {}
    dataset['data_train'] = all_data[0:num_train]
    dataset['labels_train'] = all_labels[0:num_train]
    dataset['data_val'] = all_data[num_train:]
    dataset['labels_val'] = all_labels[num_train:]
    # Train with SGD.
    num_iter = 50
    learning_rate = 0.1
    model.train_with_sgd(
        dataset, num_iter, learning_rate, batch_size=100, print_every=5)
    self.assertGreater(
        model.get_accuracy(dataset['data_train'], dataset['labels_train']), 0.8)
