python-ldl 0.0.2__tar.gz → 0.0.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. {python-ldl-0.0.2/python_ldl.egg-info → python_ldl-0.0.3}/PKG-INFO +7 -7
  2. {python-ldl-0.0.2 → python_ldl-0.0.3}/README.md +6 -5
  3. {python-ldl-0.0.2 → python_ldl-0.0.3}/pyldl/algorithms/__init__.py +6 -2
  4. {python-ldl-0.0.2 → python_ldl-0.0.3}/pyldl/algorithms/_algorithm_adaptation.py +41 -100
  5. python_ldl-0.0.3/pyldl/algorithms/_classifier.py +105 -0
  6. python_ldl-0.0.3/pyldl/algorithms/_incomplete.py +58 -0
  7. python_ldl-0.0.3/pyldl/algorithms/_label_enhancement.py +285 -0
  8. python_ldl-0.0.3/pyldl/algorithms/_ldl_da.py +182 -0
  9. python_ldl-0.0.3/pyldl/algorithms/_ldl_dpa.py +40 -0
  10. python_ldl-0.0.3/pyldl/algorithms/_ldl_lrr.py +39 -0
  11. {python-ldl-0.0.2 → python_ldl-0.0.3}/pyldl/algorithms/_ldl_scl.py +19 -32
  12. python_ldl-0.0.3/pyldl/algorithms/_ldlf.py +84 -0
  13. {python-ldl-0.0.2 → python_ldl-0.0.3}/pyldl/algorithms/_problem_transformation.py +15 -23
  14. python_ldl-0.0.3/pyldl/algorithms/base.py +357 -0
  15. {python-ldl-0.0.2 → python_ldl-0.0.3}/pyldl/applications/emphasis_selection.py +26 -27
  16. python_ldl-0.0.3/pyldl/applications/facial_emotion_recognition.py +209 -0
  17. {python-ldl-0.0.2 → python_ldl-0.0.3}/pyldl/applications/lesion_counting.py +39 -46
  18. python_ldl-0.0.3/pyldl/metrics.py +144 -0
  19. {python-ldl-0.0.2 → python_ldl-0.0.3}/pyldl/utils.py +45 -1
  20. {python-ldl-0.0.2 → python_ldl-0.0.3/python_ldl.egg-info}/PKG-INFO +7 -7
  21. {python-ldl-0.0.2 → python_ldl-0.0.3}/python_ldl.egg-info/SOURCES.txt +2 -0
  22. {python-ldl-0.0.2 → python_ldl-0.0.3}/python_ldl.egg-info/requires.txt +0 -1
  23. {python-ldl-0.0.2 → python_ldl-0.0.3}/setup.py +1 -2
  24. python-ldl-0.0.2/pyldl/algorithms/_classifier.py +0 -133
  25. python-ldl-0.0.2/pyldl/algorithms/_incomplete.py +0 -45
  26. python-ldl-0.0.2/pyldl/algorithms/_label_enhancement.py +0 -328
  27. python-ldl-0.0.2/pyldl/algorithms/_ldl_lrr.py +0 -49
  28. python-ldl-0.0.2/pyldl/algorithms/_ldlf.py +0 -89
  29. python-ldl-0.0.2/pyldl/algorithms/base.py +0 -226
  30. python-ldl-0.0.2/pyldl/applications/facial_emotion_recognition.py +0 -60
  31. python-ldl-0.0.2/pyldl/metrics.py +0 -99
  32. {python-ldl-0.0.2 → python_ldl-0.0.3}/LICENSE +0 -0
  33. {python-ldl-0.0.2 → python_ldl-0.0.3}/pyldl/__init__.py +0 -0
  34. {python-ldl-0.0.2 → python_ldl-0.0.3}/pyldl/algorithms/_ensemble.py +0 -0
  35. {python-ldl-0.0.2 → python_ldl-0.0.3}/pyldl/algorithms/_specialized_algorithms.py +0 -0
  36. {python-ldl-0.0.2 → python_ldl-0.0.3}/pyldl/algorithms/_ssg_ldl.py +0 -0
  37. {python-ldl-0.0.2 → python_ldl-0.0.3}/pyldl/applications/__init__.py +0 -0
  38. {python-ldl-0.0.2 → python_ldl-0.0.3}/pyldl/matlab_algorithms/AA_BP_fit.m +0 -0
  39. {python-ldl-0.0.2 → python_ldl-0.0.3}/pyldl/matlab_algorithms/AA_BP_predict.m +0 -0
  40. {python-ldl-0.0.2 → python_ldl-0.0.3}/pyldl/matlab_algorithms/AA_KNN.m +0 -0
  41. {python-ldl-0.0.2 → python_ldl-0.0.3}/pyldl/matlab_algorithms/BFGS_Process.m +0 -0
  42. {python-ldl-0.0.2 → python_ldl-0.0.3}/pyldl/matlab_algorithms/PT_Bayes_fit.m +0 -0
  43. {python-ldl-0.0.2 → python_ldl-0.0.3}/pyldl/matlab_algorithms/PT_Bayes_predict.m +0 -0
  44. {python-ldl-0.0.2 → python_ldl-0.0.3}/pyldl/matlab_algorithms/PT_SVM_fit.m +0 -0
  45. {python-ldl-0.0.2 → python_ldl-0.0.3}/pyldl/matlab_algorithms/PT_SVM_predict.m +0 -0
  46. {python-ldl-0.0.2 → python_ldl-0.0.3}/pyldl/matlab_algorithms/SA_BFGS_fit.m +0 -0
  47. {python-ldl-0.0.2 → python_ldl-0.0.3}/pyldl/matlab_algorithms/SA_BFGS_predict.m +0 -0
  48. {python-ldl-0.0.2 → python_ldl-0.0.3}/pyldl/matlab_algorithms/SA_IIS_fit.m +0 -0
  49. {python-ldl-0.0.2 → python_ldl-0.0.3}/pyldl/matlab_algorithms/SA_IIS_predict.m +0 -0
  50. {python-ldl-0.0.2 → python_ldl-0.0.3}/pyldl/matlab_algorithms/__init__.py +0 -0
  51. {python-ldl-0.0.2 → python_ldl-0.0.3}/python_ldl.egg-info/dependency_links.txt +0 -0
  52. {python-ldl-0.0.2 → python_ldl-0.0.3}/python_ldl.egg-info/top_level.txt +0 -0
  53. {python-ldl-0.0.2 → python_ldl-0.0.3}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: python-ldl
3
- Version: 0.0.2
3
+ Version: 0.0.3
4
4
  Summary: Label distribution learning (LDL) and label enhancement (LE) toolkit implemented in python.
5
5
  Home-page: https://github.com/SpriteMisaka/PyLDL
6
6
  Author: SpriteMisaka
@@ -19,7 +19,6 @@ Requires-Dist: scikit-fuzzy
19
19
  Requires-Dist: scikit-learn
20
20
  Requires-Dist: scipy
21
21
  Requires-Dist: tensorflow
22
- Requires-Dist: tensorflow-addons
23
22
  Requires-Dist: tensorflow-probability
24
23
 
25
24
  # PyLDL
@@ -35,12 +34,13 @@ Label distribution learning (LDL) and label enhancement (LE) toolkit implemented
35
34
  + ([Shen et al. 2017](https://github.com/SpriteMisaka/PyLDL/blob/main/bibliography/shen2017.pdf))[*NeurIPS*]: `LDLF`.
36
35
  + ([Wang and Geng 2019](https://github.com/SpriteMisaka/PyLDL/blob/main/bibliography/wang2019.pdf))[*IJCAI*]: `LDL4C`$^3$.
37
36
  + ([Shen et al. 2020](https://github.com/SpriteMisaka/PyLDL/blob/main/bibliography/shen2020.pdf))[*南京理工大学学报* (Chinese)]: `AdaBoostLDL`.
38
- + ([González et al. 2021a](https://github.com/SpriteMisaka/PyLDL/blob/main/bibliography/gonz%C3%A1lez2021a.pdf))[*Information Sciences*]: `SSG_LDL`$^4$.
39
- + ([González et al. 2021b](https://github.com/SpriteMisaka/PyLDL/blob/main/bibliography/gonz%C3%A1lez2021b.pdf))[*Information Fusion*]: `DF_LDL`.
37
+ + ([González et al. 2021a](https://github.com/SpriteMisaka/PyLDL/blob/main/bibliography/gonz%C3%A1lez2021a.pdf))[*Inf. Sci.*]: `SSG_LDL`$^4$.
38
+ + ([González et al. 2021b](https://github.com/SpriteMisaka/PyLDL/blob/main/bibliography/gonz%C3%A1lez2021b.pdf))[*Inf. Fusion*]: `DF_LDL`.
40
39
  + ([Wang and Geng 2021a](https://github.com/SpriteMisaka/PyLDL/blob/main/bibliography/wang2021a.pdf))[*IJCAI*]: `LDL_HR`$^3$.
41
40
  + ([Wang and Geng 2021b](https://github.com/SpriteMisaka/PyLDL/blob/main/bibliography/wang2021b.pdf))[*ICML*]: `LDLM`$^3$.
42
41
  + ([Jia et al. 2021](https://github.com/SpriteMisaka/PyLDL/blob/main/bibliography/jia2021.pdf))[*TKDE*]: `LDL_SCL`.
43
- + ([Jia et al. 2023](https://github.com/SpriteMisaka/PyLDL/blob/main/bibliography/jia2023.pdf))[*TKDE*]: `LDL_LRR`.
42
+ + ([Jia et al. 2023a](https://github.com/SpriteMisaka/PyLDL/blob/main/bibliography/jia2023a.pdf))[*TKDE*]: `LDL_LRR`.
43
+ + ([Jia et al. 2023b](https://github.com/SpriteMisaka/PyLDL/blob/main/bibliography/jia2023b.pdf))[*TNNLS*]: `LDL_DPA`.
44
44
  + ([Wen et al. 2023](https://github.com/SpriteMisaka/PyLDL/blob/main/bibliography/wen2023.pdf))[*ICCV*]: `CAD`$^1$, `QFD2`$^1$, and `CJS`$^1$.
45
45
  + LE algorithms:
46
46
  + ([Xu, Liu, and Geng 2019](https://github.com/SpriteMisaka/PyLDL/blob/main/bibliography/xu2019.pdf))[*TKDE*]: `FCM`, `KM`, `LP`, `ML`, and `GLLE`.
@@ -49,9 +49,10 @@ Label distribution learning (LDL) and label enhancement (LE) toolkit implemented
49
49
  + LDL metrics: `chebyshev`, `clark`, `canberra`, `kl_divergence`, `cosine`, `intersection`, etc.
50
50
  + Structured LDL datasets: *Human_Gene*, *Movie*, *Natural_Scene*, *s-BU_3DFE*, *s-JAFFE*, *Yeast*, etc.
51
51
  + LDL applications:
52
- + Facial emotion recognition (supported datasets: [*JAFFE*](https://zenodo.org/records/3451524)).
52
+ + Facial emotion recognition (supported datasets: [*JAFFE*](https://zenodo.org/records/3451524))
53
53
  + ([Shirani et al. 2019](https://github.com/SpriteMisaka/PyLDL/blob/main/bibliography/shirani2019.pdf))[*ACL*]: Emphasis selection (supported datasets: [*SemEval2020*](https://github.com/RiTUAL-UH/SemEval2020_Task10_Emphasis_Selection); pre-trained GloVe embeddings can be downloaded [here](https://nlp.stanford.edu/projects/glove/)).
54
54
  + ([Wu et al. 2019](https://github.com/SpriteMisaka/PyLDL/blob/main/bibliography/wu2019.pdf))[*ICCV*]: Lesion counting (supported datasets: [*ACNE04*](https://drive.google.com/drive/folders/18yJcHXhzOv7H89t-Lda6phheAicLqMuZ)).
55
+ + ([Chen et al. 2020](https://github.com/SpriteMisaka/PyLDL/blob/main/bibliography/chen2020.pdf))[*CVPR*]: Facial emotion recognition with auxiliary label space graphs (supported datasets: [*CK+*](https://www.jeffcohn.net/Resources/); OpenFace can be downloaded [here](https://github.com/TadasBaltrusaitis/OpenFace/releases), and the required models can be downloaded [here](https://github.com/TadasBaltrusaitis/OpenFace/wiki/Model-download)).
55
56
 
56
57
  > $^1$ Technically, these methods are only suitable for totally ordered labels.
57
58
  >
@@ -181,7 +182,6 @@ scikit-fuzzy>=0.4.2
181
182
  scikit-learn>=1.0.2
182
183
  scipy>=1.8.0
183
184
  tensorflow>=2.8.0
184
- tensorflow-addons>=0.22.0
185
185
  tensorflow-probability>=0.16.0
186
186
  ```
187
187
 
@@ -11,12 +11,13 @@ Label distribution learning (LDL) and label enhancement (LE) toolkit implemented
11
11
  + ([Shen et al. 2017](https://github.com/SpriteMisaka/PyLDL/blob/main/bibliography/shen2017.pdf))[*NeurIPS*]: `LDLF`.
12
12
  + ([Wang and Geng 2019](https://github.com/SpriteMisaka/PyLDL/blob/main/bibliography/wang2019.pdf))[*IJCAI*]: `LDL4C`$^3$.
13
13
  + ([Shen et al. 2020](https://github.com/SpriteMisaka/PyLDL/blob/main/bibliography/shen2020.pdf))[*南京理工大学学报* (Chinese)]: `AdaBoostLDL`.
14
- + ([González et al. 2021a](https://github.com/SpriteMisaka/PyLDL/blob/main/bibliography/gonz%C3%A1lez2021a.pdf))[*Information Sciences*]: `SSG_LDL`$^4$.
15
- + ([González et al. 2021b](https://github.com/SpriteMisaka/PyLDL/blob/main/bibliography/gonz%C3%A1lez2021b.pdf))[*Information Fusion*]: `DF_LDL`.
14
+ + ([González et al. 2021a](https://github.com/SpriteMisaka/PyLDL/blob/main/bibliography/gonz%C3%A1lez2021a.pdf))[*Inf. Sci.*]: `SSG_LDL`$^4$.
15
+ + ([González et al. 2021b](https://github.com/SpriteMisaka/PyLDL/blob/main/bibliography/gonz%C3%A1lez2021b.pdf))[*Inf. Fusion*]: `DF_LDL`.
16
16
  + ([Wang and Geng 2021a](https://github.com/SpriteMisaka/PyLDL/blob/main/bibliography/wang2021a.pdf))[*IJCAI*]: `LDL_HR`$^3$.
17
17
  + ([Wang and Geng 2021b](https://github.com/SpriteMisaka/PyLDL/blob/main/bibliography/wang2021b.pdf))[*ICML*]: `LDLM`$^3$.
18
18
  + ([Jia et al. 2021](https://github.com/SpriteMisaka/PyLDL/blob/main/bibliography/jia2021.pdf))[*TKDE*]: `LDL_SCL`.
19
- + ([Jia et al. 2023](https://github.com/SpriteMisaka/PyLDL/blob/main/bibliography/jia2023.pdf))[*TKDE*]: `LDL_LRR`.
19
+ + ([Jia et al. 2023a](https://github.com/SpriteMisaka/PyLDL/blob/main/bibliography/jia2023a.pdf))[*TKDE*]: `LDL_LRR`.
20
+ + ([Jia et al. 2023b](https://github.com/SpriteMisaka/PyLDL/blob/main/bibliography/jia2023b.pdf))[*TNNLS*]: `LDL_DPA`.
20
21
  + ([Wen et al. 2023](https://github.com/SpriteMisaka/PyLDL/blob/main/bibliography/wen2023.pdf))[*ICCV*]: `CAD`$^1$, `QFD2`$^1$, and `CJS`$^1$.
21
22
  + LE algorithms:
22
23
  + ([Xu, Liu, and Geng 2019](https://github.com/SpriteMisaka/PyLDL/blob/main/bibliography/xu2019.pdf))[*TKDE*]: `FCM`, `KM`, `LP`, `ML`, and `GLLE`.
@@ -25,9 +26,10 @@ Label distribution learning (LDL) and label enhancement (LE) toolkit implemented
25
26
  + LDL metrics: `chebyshev`, `clark`, `canberra`, `kl_divergence`, `cosine`, `intersection`, etc.
26
27
  + Structured LDL datasets: *Human_Gene*, *Movie*, *Natural_Scene*, *s-BU_3DFE*, *s-JAFFE*, *Yeast*, etc.
27
28
  + LDL applications:
28
- + Facial emotion recognition (supported datasets: [*JAFFE*](https://zenodo.org/records/3451524)).
29
+ + Facial emotion recognition (supported datasets: [*JAFFE*](https://zenodo.org/records/3451524))
29
30
  + ([Shirani et al. 2019](https://github.com/SpriteMisaka/PyLDL/blob/main/bibliography/shirani2019.pdf))[*ACL*]: Emphasis selection (supported datasets: [*SemEval2020*](https://github.com/RiTUAL-UH/SemEval2020_Task10_Emphasis_Selection); pre-trained GloVe embeddings can be downloaded [here](https://nlp.stanford.edu/projects/glove/)).
30
31
  + ([Wu et al. 2019](https://github.com/SpriteMisaka/PyLDL/blob/main/bibliography/wu2019.pdf))[*ICCV*]: Lesion counting (supported datasets: [*ACNE04*](https://drive.google.com/drive/folders/18yJcHXhzOv7H89t-Lda6phheAicLqMuZ)).
32
+ + ([Chen et al. 2020](https://github.com/SpriteMisaka/PyLDL/blob/main/bibliography/chen2020.pdf))[*CVPR*]: Facial emotion recognition with auxiliary label space graphs (supported datasets: [*CK+*](https://www.jeffcohn.net/Resources/); OpenFace can be downloaded [here](https://github.com/TadasBaltrusaitis/OpenFace/releases), and the required models can be downloaded [here](https://github.com/TadasBaltrusaitis/OpenFace/wiki/Model-download)).
31
33
 
32
34
  > $^1$ Technically, these methods are only suitable for totally ordered labels.
33
35
  >
@@ -157,7 +159,6 @@ scikit-fuzzy>=0.4.2
157
159
  scikit-learn>=1.0.2
158
160
  scipy>=1.8.0
159
161
  tensorflow>=2.8.0
160
- tensorflow-addons>=0.22.0
161
162
  tensorflow-probability>=0.16.0
162
163
  ```
163
164
 
@@ -9,18 +9,22 @@ from ._ensemble import DF_LDL, AdaBoostLDL
9
9
  from ._ldlf import LDLF
10
10
  from ._ldl_scl import LDL_SCL
11
11
  from ._ldl_lrr import LDL_LRR
12
+ from ._ldl_dpa import LDL_DPA
12
13
 
13
14
  from ._ssg_ldl import SSG_LDL
14
15
 
15
16
  from ._label_enhancement import FCM, KM, LP, ML, GLLE, LEVI, LIBLE
16
17
 
18
+ from ._ldl_da import LDL_DA
19
+
17
20
 
18
21
  __all__ = ["SA_BFGS", "SA_IIS", "AA_KNN", "AA_BP", "PT_Bayes", "PT_SVM",
19
22
  "CPNN", "BCPNN", "ACPNN", "LDSVR",
20
- "LDLF", "LDL_SCL", "LDL_LRR", "CAD", "QFD2", "CJS",
23
+ "LDLF", "LDL_SCL", "LDL_LRR", "LDL_DPA", "CAD", "QFD2", "CJS",
21
24
  "DF_LDL", "AdaBoostLDL",
22
25
  "LDL4C", "LDL_HR", "LDLM",
23
26
  "IncomLDL",
24
27
  "SSG_LDL",
25
28
  "FCM", "KM", "LP", "ML", "GLLE",
26
- "LEVI", 'LIBLE']
29
+ "LEVI", "LIBLE",
30
+ "LDL_DA"]
@@ -1,128 +1,74 @@
1
1
  import numpy as np
2
2
  from sklearn.neighbors import NearestNeighbors
3
- from sklearn.preprocessing import OneHotEncoder
4
3
 
5
4
  import keras
6
5
  import tensorflow as tf
7
6
  from keras import backend as K
8
7
 
9
- from pyldl.algorithms.base import BaseLDL, BaseDeepLDL
8
+ from pyldl.algorithms.base import BaseLDL, BaseDeepLDL, BaseGD, BaseAdam
10
9
 
11
10
 
12
11
  class AA_KNN(BaseLDL):
13
12
 
14
- def __init__(self,
15
- k=5,
16
- random_state=None):
17
-
18
- super().__init__(random_state)
19
-
20
- self.k = k
21
- self._model = NearestNeighbors(n_neighbors=self.k)
22
-
23
- def fit(self, X, y):
13
+ def fit(self, X, y, k=5):
24
14
  super().fit(X, y)
25
- self._model.fit(self._X)
15
+ self._model = NearestNeighbors(n_neighbors=k).fit(self._X)
16
+ return self
26
17
 
27
18
  def predict(self, X):
28
19
  _, inds = self._model.kneighbors(X)
29
20
  return np.average(self._y[inds], axis=1)
30
21
 
31
22
 
32
- class AA_BP(BaseDeepLDL):
23
+ class AA_BP(BaseGD, BaseDeepLDL):
24
+ pass
33
25
 
34
- def __init__(self, n_hidden=None, n_latent=None, random_state=None):
35
- super().__init__(n_hidden, n_latent, random_state)
36
26
 
37
- @tf.function
38
- def _loss_function(self, y, y_pred):
39
- return tf.math.reduce_mean(keras.losses.mean_squared_error(y, y_pred))
40
-
41
- def fit(self, X, y, learning_rate=5e-3, epochs=3000, batch_size=32,
42
- model=None, activation='sigmoid', optimizer='SGD', X_test=None, y_test=None):
43
- super().fit(X, y)
44
-
45
- self._batch_size = batch_size
46
-
47
- if self._n_hidden is None:
48
- self._n_hidden = self._n_features * 3 // 2
49
-
50
- self._model = model
51
- if self._model is None:
52
- self._model = keras.Sequential([keras.layers.InputLayer(input_shape=(self._n_features,)),
53
- keras.layers.Dense(self._n_hidden, activation=activation),
54
- keras.layers.Dense(self._n_outputs, activation='softmax')])
55
- self._optimizer = eval(f'keras.optimizers.{optimizer}({learning_rate})')
56
- data = tf.data.Dataset.from_tensor_slices((self._X, self._y)).batch(self._batch_size)
57
-
58
- for _ in range(epochs):
59
- total_loss = 0.
60
- for batch in data:
61
- with tf.GradientTape() as tape:
62
- y_pred = self._model(batch[0])
63
- loss = self._loss_function(batch[1], y_pred)
64
- gradients = tape.gradient(loss, self.trainable_variables)
65
- self._optimizer.apply_gradients(zip(gradients, self.trainable_variables))
66
- total_loss += loss
67
-
68
- def predict(self, X):
69
- return self._model(X)
70
-
71
-
72
- class CAD(AA_BP):
27
+ class CAD(BaseAdam, BaseDeepLDL):
73
28
 
29
+ @staticmethod
74
30
  @tf.function
75
- def _loss_function(self, y, y_pred):
31
+ def loss_function(y, y_pred):
76
32
  def _CAD(y, y_pred):
77
33
  return tf.reduce_mean(tf.abs(
78
34
  tf.cumsum(y, axis=1) - tf.cumsum(y_pred, axis=1)
79
35
  ), axis=1)
80
36
  return tf.math.reduce_sum(
81
37
  tf.map_fn(lambda i: _CAD(y[:, :i], y_pred[:, :i]),
82
- tf.range(1, self._n_outputs + 1),
38
+ tf.range(1, y.shape[1] + 1),
83
39
  fn_output_signature=tf.float32)
84
40
  )
85
41
 
86
- def fit(self, X, y, learning_rate=1e-4, epochs=500,
87
- activation='relu', optimizer='Adam'):
88
- return super().fit(X, y, learning_rate, epochs, activation, optimizer)
89
-
90
42
 
91
- class QFD2(AA_BP):
43
+ class QFD2(BaseAdam, BaseDeepLDL):
92
44
 
45
+ @staticmethod
93
46
  @tf.function
94
- def _loss_function(self, y, y_pred):
47
+ def _loss_function(y, y_pred):
95
48
  Q = y - y_pred
96
- j = tf.reshape(tf.range(self._n_outputs), [self._n_outputs, 1])
97
- k = tf.reshape(tf.range(self._n_outputs), [1, self._n_outputs])
98
- A = tf.cast(1 - tf.abs(j - k) / (self._n_outputs - 1), dtype=tf.float32)
49
+ j = tf.reshape(tf.range(y.shape[1]), [y.shape[1], 1])
50
+ k = tf.reshape(tf.range(y.shape[1]), [1, y.shape[1]])
51
+ A = tf.cast(1 - tf.abs(j - k) / (y.shape[1] - 1), dtype=tf.float32)
99
52
  return tf.math.reduce_mean(
100
53
  tf.linalg.diag_part(tf.matmul(tf.matmul(Q, A), tf.transpose(Q)))
101
54
  )
102
55
 
103
- def fit(self, X, y, learning_rate=1e-4, epochs=500,
104
- activation='relu', optimizer='Adam'):
105
- return super().fit(X, y, learning_rate, epochs, activation, optimizer)
106
56
 
57
+ class CJS(BaseAdam, BaseDeepLDL):
107
58
 
108
- class CJS(AA_BP):
109
-
59
+ @staticmethod
110
60
  @tf.function
111
- def _loss_function(self, y, y_pred):
61
+ def loss_function(y, y_pred):
112
62
  def _CJS(y, y_pred):
113
63
  m = 0.5 * (y + y_pred)
114
64
  js = 0.5 * (keras.losses.kl_divergence(y, m) + keras.losses.kl_divergence(y_pred, m))
115
65
  return tf.reduce_mean(js)
116
66
  return tf.math.reduce_sum(
117
67
  tf.map_fn(lambda i: _CJS(y[:, :i], y_pred[:, :i]),
118
- tf.range(1, self._n_outputs + 1),
68
+ tf.range(1, y.shape[1] + 1),
119
69
  fn_output_signature=tf.float32)
120
70
  )
121
71
 
122
- def fit(self, X, y, learning_rate=1e-4, epochs=500,
123
- activation='relu', optimizer='Adam'):
124
- return super().fit(X, y, learning_rate, epochs, activation, optimizer)
125
-
126
72
 
127
73
  class RProp(keras.optimizers.Optimizer):
128
74
 
@@ -134,6 +80,10 @@ class RProp(keras.optimizers.Optimizer):
134
80
  self.min_alpha = K.variable(min_alpha, name='min_alpha')
135
81
  self.max_alpha = K.variable(max_alpha, name='max_alpha')
136
82
 
83
+ def apply_gradients(self, grads_and_vars):
84
+ grads, trainable_variables = zip(*grads_and_vars)
85
+ self.get_updates(trainable_variables, grads)
86
+
137
87
  def get_updates(self, params, gradients):
138
88
  grads = gradients
139
89
  shapes = [K.int_shape(p) for p in params]
@@ -183,12 +133,12 @@ class RProp(keras.optimizers.Optimizer):
183
133
  return dict(list(base_config.items()) + list(config.items()))
184
134
 
185
135
 
186
- class CPNN(BaseDeepLDL):
136
+ class CPNN(BaseGD, BaseDeepLDL):
187
137
 
188
138
  def _not_proper_mode(self):
189
139
  raise ValueError("The argument 'mode' can only be 'none', 'binary' or 'augment'.")
190
140
 
191
- def __init__(self, mode='none', v=5, n_hidden=None, n_latent=None, random_state=None):
141
+ def __init__(self, mode='none', v=5, n_hidden=64, n_latent=None, random_state=None):
192
142
  super().__init__(n_hidden, n_latent, random_state)
193
143
  if mode == 'none' or mode == 'binary' or mode == 'augment':
194
144
  self._mode = mode
@@ -196,37 +146,34 @@ class CPNN(BaseDeepLDL):
196
146
  self._not_proper_mode()
197
147
  self._v = v
198
148
 
199
- def fit(self, X, y, learning_rate=5e-3, epochs=3000):
200
- super().fit(X, y)
149
+ @staticmethod
150
+ @tf.function
151
+ def loss_function(y, y_pred):
152
+ return tf.math.reduce_mean(keras.losses.kl_divergence(y, y_pred))
201
153
 
202
- self._optimizer = RProp(init_alpha=learning_rate)
154
+ def _get_default_model(self):
155
+ input_shape = (self._n_features + (1 if self._mode == 'none' else self._n_outputs),)
156
+ return keras.Sequential([keras.layers.InputLayer(input_shape=input_shape),
157
+ keras.layers.Dense(self._n_hidden, activation='sigmoid'),
158
+ keras.layers.Dense(1, activation=None)])
203
159
 
204
- if self._n_hidden is None:
205
- self._n_hidden = self._n_features * 3 // 2
160
+ def _get_default_optimizer(self):
161
+ return RProp()
206
162
 
163
+ def _before_train(self):
207
164
  if self._mode == 'augment':
165
+ n = self._X.shape[0]
208
166
  one_hot = tf.one_hot(tf.math.argmax(self._y, axis=1), self.n_outputs)
209
167
  self._X = tf.repeat(self._X, self._v, axis=0)
210
168
  self._y = tf.repeat(self._y, self._v, axis=0)
211
169
  one_hot = tf.repeat(one_hot, self._v, axis=0)
212
- v = tf.reshape(tf.tile([1 / (i + 1) for i in range(self._v)], [X.shape[0]]), (-1, 1))
170
+ v = tf.reshape(tf.tile([1 / (i + 1) for i in range(self._v)], [n]), (-1, 1))
213
171
  self._y += self._y * one_hot * v
214
172
 
215
- input_shape = (self._n_features + (1 if self._mode == 'none' else self._n_outputs),)
216
- self._model = keras.Sequential([keras.layers.InputLayer(input_shape=input_shape),
217
- keras.layers.Dense(self._n_hidden, activation='sigmoid'),
218
- keras.layers.Dense(1, activation=None)])
219
-
220
- for _ in range(epochs):
221
- with tf.GradientTape() as tape:
222
- loss = self._loss(self._X, self._y)
223
- gradients = tape.gradient(loss, self.trainable_variables)
224
- self._optimizer.get_updates(self.trainable_variables, gradients)
225
-
226
173
  def _make_inputs(self, X):
227
174
  temp = tf.reshape(tf.tile([i + 1 for i in range(self._n_outputs)], [X.shape[0]]), (-1, 1))
228
175
  if self._mode != 'none':
229
- temp = OneHotEncoder(sparse=False).fit_transform(temp)
176
+ temp = tf.one_hot(tf.reshape(temp, (-1, )) - 1, depth=self._n_outputs)
230
177
  return tf.concat([tf.cast(tf.repeat(X, self._n_outputs, axis=0), dtype=tf.float32),
231
178
  tf.cast(temp, dtype=tf.float32)],
232
179
  axis=1)
@@ -238,12 +185,6 @@ class CPNN(BaseDeepLDL):
238
185
  b = tf.reshape(-tf.math.log(tf.math.reduce_sum(tf.math.exp(results), axis=1)), (-1, 1))
239
186
  return tf.math.exp(b + results)
240
187
 
241
- def _loss(self, X, y):
242
- return tf.math.reduce_mean(keras.losses.kl_divergence(y, self._call(X)))
243
-
244
- def predict(self, X):
245
- return self._call(X)
246
-
247
188
 
248
189
  class BCPNN(CPNN):
249
190
 
@@ -0,0 +1,105 @@
1
+ import keras
2
+ import tensorflow as tf
3
+
4
+ from pyldl.algorithms.base import BaseDeepLDLClassifier, BaseGD, BaseBFGS
5
+
6
+
7
+ class LDL4C(BaseBFGS, BaseDeepLDLClassifier):
8
+ """LDL4C is proposed in paper Classification with Label Distribution Learning.
9
+ """
10
+
11
+ @tf.function
12
+ def _loss(self, params_1d):
13
+ y_pred = keras.activations.softmax(self._X @ self._params2model(params_1d)[0])
14
+ top2 = tf.gather(y_pred, self._top2, axis=1, batch_dims=1)
15
+ margin = tf.reduce_sum(tf.maximum(0., 1. - (top2[:, 0] - top2[:, 1]) / self._rho))
16
+ mae = keras.losses.mean_absolute_error(self._y, y_pred)
17
+ return tf.reduce_sum(self._entropy * mae) + self._alpha * margin + self._beta * self._l2_reg(self._model)
18
+
19
+ def _before_train(self):
20
+ self._top2 = tf.math.top_k(self._y, k=2)[1]
21
+ self._entropy = tf.cast(-tf.reduce_sum(self._y * tf.math.log(self._y) + 1e-7, axis=1), dtype=tf.float32)
22
+
23
+ def fit(self, X, y, alpha=1e-2, beta=1e-6, rho=1e-2, **kwargs):
24
+ self._alpha = alpha
25
+ self._beta = beta
26
+ self._rho = rho
27
+ return super().fit(X, y, **kwargs)
28
+
29
+
30
+ class LDL_HR(BaseBFGS, BaseDeepLDLClassifier):
31
+ """LDL-HR is proposed in paper Learn the Highest Label and Rest Label Description Degrees.
32
+ """
33
+
34
+ @tf.function
35
+ def _loss(self, params_1d):
36
+ y_pred = keras.activations.softmax(self._X @ self._params2model(params_1d)[0])
37
+
38
+ highest = tf.gather(y_pred, self._highest, axis=1, batch_dims=1)
39
+ rest = tf.gather(y_pred, self._rest, axis=1, batch_dims=1)
40
+ margin = tf.reduce_sum(tf.maximum(0., 1. - (highest - rest) / self._rho))
41
+
42
+ real_rest = tf.gather(self._y, self._rest, axis=1, batch_dims=1)
43
+ rest_mae = tf.reduce_sum(keras.losses.mean_absolute_error(real_rest, rest))
44
+
45
+ mae = tf.reduce_sum(keras.losses.mean_absolute_error(self._l, y_pred))
46
+
47
+ return mae + self._alpha * margin + self._beta * rest_mae + self._gamma * self._l2_reg(self._model)
48
+
49
+ def _before_train(self):
50
+ temp = tf.math.top_k(self._y, k=self._n_outputs)[1]
51
+ self._highest = temp[:, 0:1]
52
+ self._rest = temp[:, 1:]
53
+ self._l = tf.one_hot(tf.reshape(self._highest, -1), self._n_outputs)
54
+
55
+ def fit(self, X, y, alpha=1e-2, beta=1e-2, gamma=1e-6, rho=1e-2, **kwargs):
56
+ self._alpha = alpha
57
+ self._beta = beta
58
+ self._gamma = gamma
59
+ self._rho = rho
60
+ return super().fit(X, y, **kwargs)
61
+
62
+
63
+ class LDLM(BaseGD, BaseDeepLDLClassifier):
64
+ """LDLM is proposed in paper Label Distribution Learning Machine.
65
+ """
66
+
67
+ @tf.function
68
+ def _loss(self, X, y, start, end):
69
+ y_pred = self._model(X)
70
+
71
+ pred_margin = tf.reduce_sum(tf.clip_by_value(
72
+ tf.reduce_sum(tf.abs(self._l[start:end] - y_pred), axis=1) - self._rho,
73
+ 0., float('inf')))
74
+
75
+ highest = tf.gather(y_pred, self._highest[start:end], axis=1, batch_dims=1)
76
+ rest = tf.gather(y_pred, self._rest[start:end], axis=1, batch_dims=1)
77
+ label_margin = tf.reduce_sum(tf.maximum(0., 1. - (highest - rest) / self._rho))
78
+
79
+ second_margin = tf.reduce_sum(tf.clip_by_value(
80
+ tf.reduce_sum(tf.abs((y - y_pred) * self._neg_l[start:end]), axis=1) - self._second_margin[start:end],
81
+ 0., float('inf')))
82
+
83
+ return pred_margin + self._alpha * label_margin + \
84
+ self._beta * second_margin + self._gamma * self._l2_reg(self._model)
85
+
86
+ def _before_train(self):
87
+ temp = tf.math.top_k(self._y, k=self._n_outputs)[1]
88
+ self._highest = temp[:, 0:1]
89
+ self._rest = temp[:, 1:]
90
+
91
+ temp = tf.math.top_k(tf.gather(self._y, self._rest, axis=1, batch_dims=1), k=2)[0]
92
+ self._second_margin = temp[:, 0] - temp[:, 1]
93
+
94
+ self._l = tf.one_hot(tf.reshape(self._highest, -1), self._n_outputs)
95
+ self._neg_l = tf.where(tf.equal(self._l, 0.), 1., 0.)
96
+
97
+ def _get_default_model(self):
98
+ return self.get_2layer_model(self._n_features, self._n_outputs)
99
+
100
+ def fit(self, X, y, alpha=1e-2, beta=1e-2, gamma=1e-6, rho=1e-2, **kwargs):
101
+ self._alpha = alpha
102
+ self._beta = beta
103
+ self._gamma = gamma
104
+ self._rho = rho
105
+ return super().fit(X, y, **kwargs)
@@ -0,0 +1,58 @@
1
+ import numpy as np
2
+
3
+ from qpsolvers import solve_qp
4
+
5
+ from pyldl.algorithms.base import BaseLDL
6
+
7
+
8
+ class IncomLDL(BaseLDL):
9
+ """IncomLDL is proposed in paper Incomplete Label Distribution Learning.
10
+ """
11
+
12
+ @staticmethod
13
+ def svt(A, tau):
14
+ U, S, VT = np.linalg.svd(A, full_matrices=False)
15
+ S_thresh = np.maximum(S - tau, 0)
16
+ return U @ np.diag(S_thresh) @ VT
17
+
18
+ def _update_Z(self):
19
+ A = self._X @ self._W + self._V / self._rho
20
+ tau = self._alpha / self._rho
21
+ self._Z = self.svt(A, tau)
22
+
23
+ def _update_W(self):
24
+
25
+ G = -np.eye(self._n_outputs, dtype=np.float64)
26
+ h = np.zeros((self._n_outputs, 1), dtype=np.float64)
27
+ A = np.ones((1, self._n_outputs), dtype=np.float64)
28
+ b = np.array([1.], dtype=np.float64)
29
+
30
+ M = np.zeros_like(self._y)
31
+
32
+ for i in range(self._X.shape[0]):
33
+ P = np.diag((1 + self._rho) * self._mask[i] + self._rho * (1 - self._mask[i])).astype(np.float64)
34
+ ql = (self._V[i] - self._y[i] * self._mask[i] - self._rho * self._Z[i]) * self._mask[i]
35
+ qr = (self._V[i] - self._rho * self._Z[i]) * (1 - self._mask[i])
36
+ q = np.transpose(ql + qr).astype(np.float64)
37
+ M[i] = solve_qp(P, q, G, h, A, b, solver='quadprog')
38
+
39
+ self._W = np.linalg.pinv(np.transpose(self._X) @ self._X) @ np.transpose(self._X) @ M
40
+
41
+ def _update_V(self):
42
+ self._V = self._V + self._rho * (self._X @ self._W - self._Z)
43
+
44
+ def fit(self, X, y, mask, alpha=1e-3, rho=1., max_iterations=100):
45
+ super().fit(X, y)
46
+ self._alpha = alpha
47
+ self._rho = rho
48
+ self._mask = np.where(mask, 0., 1.)
49
+ self._W = np.ones((self._n_features, self._n_outputs))
50
+ self._Z = np.ones((self._X.shape[0], self._n_outputs))
51
+ self._V = np.ones((self._X.shape[0], self._n_outputs))
52
+ for _ in range(max_iterations):
53
+ self._update_W()
54
+ self._update_Z()
55
+ self._update_V()
56
+
57
+ def predict(self, X):
58
+ return X @ self._W