class TestCupySomHex(unittest.TestCase): def setUp(self): self.som = XPySom(5, 5, 1, topology='hexagonal', std_coeff=np.sqrt(np.pi)) self.minisom = MiniSom(5, 5, 1, topology='hexagonal') for i in range(5): for j in range(5): # checking weights normalization np.testing.assert_almost_equal(1.0, np.linalg.norm(self.som._weights[i, j])) self.som._weights = np.zeros((5, 5, 1)) # fake weights self.som._weights[2, 3] = 5.0 self.som._weights[1, 1] = 2.0 np.random.seed(1234) cp.random.seed(1234) def test_gaussian(self): cx, cy = cp.meshgrid(cp.arange(5), cp.arange(5)) c = (cx.flatten(), cy.flatten()) cs_gauss = cp.asnumpy(gaussian_generic(self.som._xx, self.som._yy, self.som._std_coeff, c, 1)) for i in range(len(c[0])): x = cp.asnumpy(c[0][i]).item() y = cp.asnumpy(c[1][i]).item() ms_gauss = self.minisom._gaussian((x,y), 1) np.testing.assert_array_almost_equal(ms_gauss, cs_gauss[i]) def test_mexican_hat(self): cx, cy = cp.meshgrid(cp.arange(5), cp.arange(5)) c = (cx.flatten(), cy.flatten()) cs_mex = cp.asnumpy(mexican_hat_generic(self.som._xx, self.som._yy, self.som._std_coeff, c, 1)) for i in range(len(c[0])): x = cp.asnumpy(c[0][i]).item() y = cp.asnumpy(c[1][i]).item() ms_mex = self.minisom._mexican_hat((x,y), 1) np.testing.assert_array_almost_equal(ms_mex, cs_mex[i]) def test_bubble(self): cx, cy = cp.meshgrid(cp.arange(5), cp.arange(5)) c = (cx.flatten(), cy.flatten()) cs_mex = cp.asnumpy(bubble(self.som._neigx, self.som._neigy, c, 1)) for i in range(len(c[0])): x = cp.asnumpy(c[0][i]).item() y = cp.asnumpy(c[1][i]).item() ms_mex = self.minisom._bubble((x,y), 1) np.testing.assert_array_almost_equal(ms_mex, cs_mex[i])
class TestMinisom(unittest.TestCase): def setUp(self): self.som = MiniSom(5, 5, 1) for i in range(5): for j in range(5): # checking weights normalization assert_almost_equal(1.0, linalg.norm(self.som._weights[i, j])) self.som._weights = zeros((5, 5, 1)) # fake weights self.som._weights[2, 3] = 5.0 self.som._weights[1, 1] = 2.0 def test_decay_function(self): assert self.som._decay_function(1., 2., 3.) == 1. / (1. + 2. / (3. / 2)) def test_fast_norm(self): assert fast_norm(array([1, 3])) == sqrt(1 + 9) def test_check_input_len(self): with self.assertRaises(ValueError): self.som.train_batch([[1, 2]], 1) with self.assertRaises(ValueError): self.som.random_weights_init(array([[1, 2]])) with self.assertRaises(ValueError): self.som._check_input_len(array([[1, 2]])) self.som._check_input_len(array([[1]])) self.som._check_input_len([[1]]) def test_unavailable_neigh_function(self): with self.assertRaises(ValueError): MiniSom(5, 5, 1, neighborhood_function='boooom') def test_gaussian(self): bell = self.som._gaussian((2, 2), 1) assert bell.max() == 1.0 assert bell.argmax() == 12 # unravel(12) = (2,2) def test_mexican_hat(self): bell = self.som._mexican_hat((2, 2), 1) assert bell.max() == 1.0 assert bell.argmax() == 12 # unravel(12) = (2,2) def test_bubble(self): bubble = self.som._bubble((2, 2), 1) assert bubble[2, 2] == 1 assert sum(sum(bubble)) == 1 def test_triangle(self): bubble = self.som._triangle((2, 2), 1) assert bubble[2, 2] == 1 assert sum(sum(bubble)) == 1 def test_win_map(self): winners = self.som.win_map([[5.0], [2.0]]) assert winners[(2, 3)][0] == [5.0] assert winners[(1, 1)][0] == [2.0] def test_labels_map(self): labels_map = self.som.labels_map([[5.0], [2.0]], ['a', 'b']) assert labels_map[(2, 3)]['a'] == 1 assert labels_map[(1, 1)]['b'] == 1 with self.assertRaises(ValueError): self.som.labels_map([[5.0]], ['a', 'b']) def test_activation_reponse(self): response = self.som.activation_response([[5.0], [2.0]]) assert response[2, 3] == 1 assert response[1, 1] == 1 def test_activate(self): assert self.som.activate(5.0).argmin() == 13.0 # unravel(13) = (2,3) def test_quantization_error(self): assert self.som.quantization_error([[5], [2]]) == 0.0 assert self.som.quantization_error([[4], [1]]) == 1.0 def test_quantization(self): q = self.som.quantization(array([[4], [2]])) assert q[0] == 5.0 assert q[1] == 2.0 def test_random_seed(self): som1 = MiniSom(5, 5, 2, sigma=1.0, learning_rate=0.5, random_seed=1) som2 = MiniSom(5, 5, 2, sigma=1.0, learning_rate=0.5, random_seed=1) # same initialization assert_array_almost_equal(som1._weights, som2._weights) data = random.rand(100, 2) som1 = MiniSom(5, 5, 2, sigma=1.0, learning_rate=0.5, random_seed=1) som1.train_random(data, 10) som2 = MiniSom(5, 5, 2, sigma=1.0, learning_rate=0.5, random_seed=1) som2.train_random(data, 10) # same state after training assert_array_almost_equal(som1._weights, som2._weights) def test_train_batch(self): som = MiniSom(5, 5, 2, sigma=1.0, learning_rate=0.5, random_seed=1) data = array([[4, 2], [3, 1]]) q1 = som.quantization_error(data) som.train_batch(data, 10) assert q1 > som.quantization_error(data) data = array([[1, 5], [6, 7]]) q1 = som.quantization_error(data) som.train_batch(data, 10, verbose=True) assert q1 > som.quantization_error(data) def test_train_random(self): som = MiniSom(5, 5, 2, sigma=1.0, learning_rate=0.5, random_seed=1) data = array([[4, 2], [3, 1]]) q1 = som.quantization_error(data) som.train_random(data, 10) assert q1 > som.quantization_error(data) data = array([[1, 5], [6, 7]]) q1 = som.quantization_error(data) som.train_random(data, 10, verbose=True) assert q1 > som.quantization_error(data) def test_random_weights_init(self): som = MiniSom(2, 2, 2, random_seed=1) som.random_weights_init(array([[1.0, .0]])) for w in som._weights: assert_array_equal(w[0], array([1.0, .0])) def test_pca_weights_init(self): som = MiniSom(2, 2, 2) som.pca_weights_init(array([[1., 0.], [0., 1.], [1., 0.], [0., 1.]])) expected = array([[[0., -1.41421356], [-1.41421356, 0.]], [[1.41421356, 0.], [0., 1.41421356]]]) assert_array_almost_equal(som._weights, expected) def test_distance_map(self): som = MiniSom(2, 2, 2, random_seed=1) som._weights = array([[[1., 0.], [0., 1.]], [[1., 0.], [0., 1.]]]) assert_array_equal(som.distance_map(), array([[1., 1.], [1., 1.]])) def test_pickling(self): with open('som.p', 'wb') as outfile: pickle.dump(self.som, outfile) with open('som.p', 'rb') as infile: pickle.load(infile) os.remove('som.p')
class TestCupySom(unittest.TestCase): def setUp(self): self.som = XPySom(5, 5, 1, std_coeff=np.sqrt(np.pi)) self.minisom = MiniSom(5, 5, 1) for i in range(5): for j in range(5): # checking weights normalization np.testing.assert_almost_equal(1.0, np.linalg.norm(self.som._weights[i, j])) self.som._weights = np.zeros((5, 5, 1)) # fake weights self.som._weights[2, 3] = 5.0 self.som._weights[1, 1] = 2.0 np.random.seed(1234) cp.random.seed(1234) def test_unavailable_neigh_function(self): with self.assertRaises(ValueError): XPySom(5, 5, 1, neighborhood_function='boooom') def test_unavailable_distance_function(self): with self.assertRaises(ValueError): XPySom(5, 5, 1, activation_distance='ridethewave') def test_win_map(self): winners = self.som.win_map([[5.0], [2.0]]) assert winners[(2, 3)][0] == [5.0] assert winners[(1, 1)][0] == [2.0] def test_labels_map(self): labels_map = self.som.labels_map([[5.0], [2.0]], ['a', 'b']) assert labels_map[(2, 3)]['a'] == 1 assert labels_map[(1, 1)]['b'] == 1 with self.assertRaises(ValueError): self.som.labels_map([[5.0]], ['a', 'b']) def test_activation_reponse(self): response = self.som.activation_response([[5.0], [2.0]]) assert response[2, 3] == 1 assert response[1, 1] == 1 def test_activate(self): assert self.som.activate(5.0).argmin() == 13.0 # unravel(13) = (2,3) def test_distance_from_weights(self): data = np.arange(-5, 5).reshape(-1, 1) weights = self.som._weights.reshape(-1, self.som._weights.shape[2]) distances = self.som.distance_from_weights(data) for i in range(len(data)): for j in range(len(weights)): assert(distances[i][j] == np.linalg.norm(data[i] - weights[j])) def test_quantization_error(self): assert self.som.quantization_error([[5], [2]]) == 0.0 assert self.som.quantization_error([[4], [1]]) == 1.0 def test_topographic_error(self): # 5 will have bmu_1 in (2,3) and bmu_2 in (2, 4) # which are in the same neighborhood self.som._weights[2, 4] = 6.0 # 15 will have bmu_1 in (4, 4) and bmu_2 in (0, 0) # which are not in the same neighborhood self.som._weights[4, 4] = 15.0 self.som._weights[0, 0] = 14. assert self.som.topographic_error([[5]]) == 0.0 assert self.som.topographic_error([[15]]) == 1.0 def test_quantization(self): q = self.som.quantization(np.array([[4], [2]])) assert q[0] == 5.0 assert q[1] == 2.0 def test_random_seed(self): som1 = XPySom(5, 5, 2, sigma=1.0, learning_rate=0.5, random_seed=1) som2 = XPySom(5, 5, 2, sigma=1.0, learning_rate=0.5, random_seed=1) # same initialization np.testing.assert_array_almost_equal(som1._weights, som2._weights) data = np.random.rand(100, 2) som1 = XPySom(5, 5, 2, sigma=1.0, learning_rate=0.5, random_seed=1) som1.train_random(data, 10) som2 = XPySom(5, 5, 2, sigma=1.0, learning_rate=0.5, random_seed=1) som2.train_random(data, 10) # same state after training np.testing.assert_array_almost_equal(som1._weights, som2._weights) def test_train(self): som = XPySom(5, 5, 2, sigma=1.0, learning_rate=0.5, random_seed=1) data = np.array([[4, 2], [3, 1]]) q1 = som.quantization_error(data) som.train(data, 10) assert q1 > som.quantization_error(data) data = np.array([[1, 5], [6, 7]]) q1 = som.quantization_error(data) som.train(data, 10, verbose=True) assert q1 > som.quantization_error(data) def test_random_weights_init(self): som = XPySom(2, 2, 2, random_seed=1) som.random_weights_init(np.array([[1.0, .0]])) for w in som._weights: np.testing.assert_array_equal(w[0], np.array([1.0, .0])) def test_pca_weights_init(self): som = XPySom(2, 2, 2) som.pca_weights_init(np.array([[1., 0.], [0., 1.], [1., 0.], [0., 1.]])) expected = np.array([[[0., -1.41421356], [-1.41421356, 0.]], [[1.41421356, 0.], [0., 1.41421356]]]) np.testing.assert_array_almost_equal(som._weights, expected) def test_distance_map(self): som = XPySom(2, 2, 2, random_seed=1) som._weights = np.array([[[1., 0.], [0., 1.]], [[1., 0.], [0., 1.]]]) np.testing.assert_array_equal(som.distance_map(), np.array([[1., 1.], [1., 1.]])) som = MiniSom(2, 2, 2, topology='hexagonal', random_seed=1) som._weights = np.array([[[1., 0.], [0., 1.]], [[1., 0.], [0., 1.]]]) np.testing.assert_array_equal(som.distance_map(), np.array([[.5, 1.], [1., .5]])) def test_pickling(self): with open('som.p', 'wb') as outfile: pickle.dump(self.som, outfile) with open('som.p', 'rb') as infile: pickle.load(infile) os.remove('som.p') def test_euclidean_distance(self): x = np.random.rand(100, 20) w = np.random.rand(10,10,20) cs_dist = cp.asnumpy(euclidean_squared_distance(cp.array(x), cp.array(w))) cs_dist = cs_dist.reshape((100,10,10)) for i, sample in enumerate(x): ms_dist = self.minisom._euclidean_distance(sample, w)**2 np.testing.assert_array_almost_equal(ms_dist, cs_dist[i]) def test_cosine_distance(self): x = np.random.rand(100, 20) w = np.random.rand(10,10,20) cs_dist = cp.asnumpy(cosine_distance(cp.array(x), cp.array(w))) cs_dist = cs_dist.reshape((100,10,10)) for i, sample in enumerate(x): ms_dist = self.minisom._cosine_distance(sample, w) np.testing.assert_array_almost_equal(ms_dist, cs_dist[i]) def test_manhattan_distance(self): x = np.random.rand(100, 20) w = np.random.rand(10,10,20) cs_dist = cp.asnumpy(manhattan_distance(cp.array(x), cp.array(w))) cs_dist = cs_dist.reshape((100,10,10)) for i, sample in enumerate(x): ms_dist = self.minisom._manhattan_distance(sample, w) np.testing.assert_array_almost_equal(ms_dist, cs_dist[i]) def test_gaussian(self): cx, cy = cp.meshgrid(cp.arange(5), cp.arange(5)) c = (cx.flatten(), cy.flatten()) cs_gauss = cp.asnumpy(gaussian_rect(self.som._neigx, self.som._neigy, self.som._std_coeff, c, 1)) for i in range(len(c[0])): x = cp.asnumpy(c[0][i]).item() y = cp.asnumpy(c[1][i]).item() ms_gauss = self.minisom._gaussian((x,y), 1) np.testing.assert_array_almost_equal(ms_gauss, cs_gauss[i]) def test_mexican_hat(self): cx, cy = cp.meshgrid(cp.arange(5), cp.arange(5)) c = (cx.flatten(), cy.flatten()) cs_mex = cp.asnumpy(mexican_hat_rect(self.som._neigx, self.som._neigy, self.som._std_coeff, c, 1)) for i in range(len(c[0])): x = cp.asnumpy(c[0][i]).item() y = cp.asnumpy(c[1][i]).item() ms_mex = self.minisom._mexican_hat((x,y), 1) np.testing.assert_array_almost_equal(ms_mex, cs_mex[i]) def test_bubble(self): cx, cy = cp.meshgrid(cp.arange(5), cp.arange(5)) c = (cx.flatten(), cy.flatten()) cs_mex = cp.asnumpy(bubble(self.som._neigx, self.som._neigy, c, 1)) for i in range(len(c[0])): x = cp.asnumpy(c[0][i]).item() y = cp.asnumpy(c[1][i]).item() ms_mex = self.minisom._bubble((x,y), 1) np.testing.assert_array_almost_equal(ms_mex, cs_mex[i]) def test_triangle(self): cx, cy = cp.meshgrid(cp.arange(5), cp.arange(5)) c = (cx.flatten(), cy.flatten()) cs_mex = cp.asnumpy(triangle(self.som._neigx, self.som._neigy, c, 1)) for i in range(len(c[0])): x = cp.asnumpy(c[0][i]).item() y = cp.asnumpy(c[1][i]).item() ms_mex = self.minisom._triangle((x,y), 1) np.testing.assert_array_almost_equal(ms_mex, cs_mex[i])