libz 0.4__tar.gz → 0.5__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.
- {libz-0.4 → libz-0.5}/PKG-INFO +1 -1
- {libz-0.4 → libz-0.5}/libz/DLG/prac6.py +119 -119
- {libz-0.4 → libz-0.5}/libz/__init__.py +1 -1
- {libz-0.4 → libz-0.5}/libz.egg-info/PKG-INFO +1 -1
- {libz-0.4 → libz-0.5}/pyproject.toml +1 -1
- {libz-0.4 → libz-0.5}/README.md +0 -0
- {libz-0.4 → libz-0.5}/libz/AWT/__init__.py +0 -0
- {libz-0.4 → libz-0.5}/libz/AWT/prac1.py +0 -0
- {libz-0.4 → libz-0.5}/libz/AWT/prac10.py +0 -0
- {libz-0.4 → libz-0.5}/libz/AWT/prac2.py +0 -0
- {libz-0.4 → libz-0.5}/libz/AWT/prac3.py +0 -0
- {libz-0.4 → libz-0.5}/libz/AWT/prac4.py +0 -0
- {libz-0.4 → libz-0.5}/libz/AWT/prac5.py +0 -0
- {libz-0.4 → libz-0.5}/libz/AWT/prac6.py +0 -0
- {libz-0.4 → libz-0.5}/libz/AWT/prac7.py +0 -0
- {libz-0.4 → libz-0.5}/libz/AWT/prac8.py +0 -0
- {libz-0.4 → libz-0.5}/libz/AWT/prac9.py +0 -0
- {libz-0.4 → libz-0.5}/libz/BDA/__init__.py +0 -0
- {libz-0.4 → libz-0.5}/libz/BDA/prac1.py +0 -0
- {libz-0.4 → libz-0.5}/libz/BDA/prac10.py +0 -0
- {libz-0.4 → libz-0.5}/libz/BDA/prac2.py +0 -0
- {libz-0.4 → libz-0.5}/libz/BDA/prac3.py +0 -0
- {libz-0.4 → libz-0.5}/libz/BDA/prac4.py +0 -0
- {libz-0.4 → libz-0.5}/libz/BDA/prac5.py +0 -0
- {libz-0.4 → libz-0.5}/libz/BDA/prac6.py +0 -0
- {libz-0.4 → libz-0.5}/libz/BDA/prac7.py +0 -0
- {libz-0.4 → libz-0.5}/libz/BDA/prac8.py +0 -0
- {libz-0.4 → libz-0.5}/libz/BDA/prac9.py +0 -0
- {libz-0.4 → libz-0.5}/libz/BIO/__init__.py +0 -0
- {libz-0.4 → libz-0.5}/libz/BIO/prac1.py +0 -0
- {libz-0.4 → libz-0.5}/libz/BIO/prac10.py +0 -0
- {libz-0.4 → libz-0.5}/libz/BIO/prac2.py +0 -0
- {libz-0.4 → libz-0.5}/libz/BIO/prac3.py +0 -0
- {libz-0.4 → libz-0.5}/libz/BIO/prac4.py +0 -0
- {libz-0.4 → libz-0.5}/libz/BIO/prac5.py +0 -0
- {libz-0.4 → libz-0.5}/libz/BIO/prac6.py +0 -0
- {libz-0.4 → libz-0.5}/libz/BIO/prac7.py +0 -0
- {libz-0.4 → libz-0.5}/libz/BIO/prac8.py +0 -0
- {libz-0.4 → libz-0.5}/libz/BIO/prac9.py +0 -0
- {libz-0.4 → libz-0.5}/libz/DL/__init__.py +0 -0
- {libz-0.4 → libz-0.5}/libz/DL/prac1.py +0 -0
- {libz-0.4 → libz-0.5}/libz/DL/prac2.py +0 -0
- {libz-0.4 → libz-0.5}/libz/DL/prac3.py +0 -0
- {libz-0.4 → libz-0.5}/libz/DL/prac4.py +0 -0
- {libz-0.4 → libz-0.5}/libz/DL/prac5.py +0 -0
- {libz-0.4 → libz-0.5}/libz/DL/prac6.py +0 -0
- {libz-0.4 → libz-0.5}/libz/DL/prac7.py +0 -0
- {libz-0.4 → libz-0.5}/libz/DL/prac8.py +0 -0
- {libz-0.4 → libz-0.5}/libz/DL/prac9.py +0 -0
- {libz-0.4 → libz-0.5}/libz/DLG/__init__.py +0 -0
- {libz-0.4 → libz-0.5}/libz/DLG/prac1.py +0 -0
- {libz-0.4 → libz-0.5}/libz/DLG/prac2.py +0 -0
- {libz-0.4 → libz-0.5}/libz/DLG/prac3.py +0 -0
- {libz-0.4 → libz-0.5}/libz/DLG/prac4.py +0 -0
- {libz-0.4 → libz-0.5}/libz/DLG/prac5.py +0 -0
- {libz-0.4 → libz-0.5}/libz/DLG/prac7.py +0 -0
- {libz-0.4 → libz-0.5}/libz/DLG/prac8.py +0 -0
- {libz-0.4 → libz-0.5}/libz/DLG/prac9.py +0 -0
- {libz-0.4 → libz-0.5}/libz/_core.py +0 -0
- {libz-0.4 → libz-0.5}/libz.egg-info/SOURCES.txt +0 -0
- {libz-0.4 → libz-0.5}/libz.egg-info/dependency_links.txt +0 -0
- {libz-0.4 → libz-0.5}/libz.egg-info/top_level.txt +0 -0
- {libz-0.4 → libz-0.5}/setup.cfg +0 -0
{libz-0.4 → libz-0.5}/PKG-INFO
RENAMED
|
@@ -1,119 +1,119 @@
|
|
|
1
|
-
# CNN Unsupervised Feature Learning (Exemplar CNN + K-Means) - works with any image folder
|
|
2
|
-
# Folder layout: one subfolder per class (class names are used ONLY for evaluation).
|
|
3
|
-
# Press Enter to use sklearn's built-in handwritten digits.
|
|
4
|
-
import os
|
|
5
|
-
import numpy as np
|
|
6
|
-
import matplotlib.pyplot as plt
|
|
7
|
-
from PIL import Image
|
|
8
|
-
from sklearn.cluster import KMeans
|
|
9
|
-
from sklearn.metrics import adjusted_rand_score, normalized_mutual_info_score
|
|
10
|
-
from
|
|
11
|
-
from tensorflow.keras.
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
#
|
|
46
|
-
#
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
img = np.
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
x =
|
|
68
|
-
x =
|
|
69
|
-
x =
|
|
70
|
-
x =
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
exemplar_cnn
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
print(f"
|
|
89
|
-
print(f"
|
|
90
|
-
|
|
91
|
-
print("\nMost common actual classes in each cluster:")
|
|
92
|
-
for c in range(n_clusters):
|
|
93
|
-
counts = np.bincount(y[clusters == c], minlength=len(class_names))
|
|
94
|
-
top = np.argsort(counts)[::-1][:3]
|
|
95
|
-
print(f"Cluster {c}:", [(class_names[t], int(counts[t])) for t in top if counts[t] > 0])
|
|
96
|
-
|
|
97
|
-
# 6. Plot pretext loss and sample images from each cluster
|
|
98
|
-
plt.figure(figsize=(7, 4))
|
|
99
|
-
plt.plot(history.history["loss"], marker="o")
|
|
100
|
-
plt.title("Exemplar CNN Training Loss")
|
|
101
|
-
plt.xlabel("Epoch")
|
|
102
|
-
plt.ylabel("Loss")
|
|
103
|
-
plt.grid(True)
|
|
104
|
-
plt.show()
|
|
105
|
-
|
|
106
|
-
per_row = 6
|
|
107
|
-
fig, axes = plt.subplots(n_clusters, per_row, figsize=(per_row, n_clusters))
|
|
108
|
-
axes = np.array(axes).reshape(n_clusters, per_row)
|
|
109
|
-
for c in range(n_clusters):
|
|
110
|
-
members = np.where(clusters == c)[0][:per_row]
|
|
111
|
-
for j in range(per_row):
|
|
112
|
-
ax = axes[c, j]
|
|
113
|
-
ax.axis("off")
|
|
114
|
-
if j < len(members):
|
|
115
|
-
ax.imshow(X[members[j]].squeeze(), cmap="gray")
|
|
116
|
-
axes[c, 0].set_title(f"C{c}", fontsize=8, loc="left")
|
|
117
|
-
plt.suptitle("Sample images in each cluster")
|
|
118
|
-
plt.tight_layout()
|
|
119
|
-
plt.show()
|
|
1
|
+
# CNN Unsupervised Feature Learning (Exemplar CNN + K-Means) - works with any image folder
|
|
2
|
+
# Folder layout: one subfolder per class (class names are used ONLY for evaluation).
|
|
3
|
+
# Press Enter to use sklearn's built-in handwritten digits.
|
|
4
|
+
import os
|
|
5
|
+
import numpy as np
|
|
6
|
+
import matplotlib.pyplot as plt
|
|
7
|
+
from PIL import Image
|
|
8
|
+
from sklearn.cluster import KMeans
|
|
9
|
+
from sklearn.metrics import adjusted_rand_score, normalized_mutual_info_score
|
|
10
|
+
from sklearn.preprocessing import StandardScaler, normalize
|
|
11
|
+
from tensorflow.keras.models import Model
|
|
12
|
+
from tensorflow.keras.layers import Input, Conv2D, MaxPooling2D, Flatten, Dense
|
|
13
|
+
|
|
14
|
+
np.random.seed(42)
|
|
15
|
+
IMG_SIZE = 28
|
|
16
|
+
|
|
17
|
+
# 1. Load dataset
|
|
18
|
+
folder = input("Enter image folder (one subfolder per class) or press Enter for digits: ").strip().strip('"')
|
|
19
|
+
|
|
20
|
+
if folder:
|
|
21
|
+
class_names = sorted(d for d in os.listdir(folder) if os.path.isdir(os.path.join(folder, d)))
|
|
22
|
+
X, y = [], []
|
|
23
|
+
for label, name in enumerate(class_names):
|
|
24
|
+
for file in os.listdir(os.path.join(folder, name)):
|
|
25
|
+
try:
|
|
26
|
+
img = Image.open(os.path.join(folder, name, file)).convert("L")
|
|
27
|
+
except OSError:
|
|
28
|
+
continue
|
|
29
|
+
X.append(np.array(img.resize((IMG_SIZE, IMG_SIZE))))
|
|
30
|
+
y.append(label)
|
|
31
|
+
X = np.array(X, dtype="float32") / 255.0
|
|
32
|
+
y = np.array(y)
|
|
33
|
+
else:
|
|
34
|
+
from sklearn.datasets import load_digits
|
|
35
|
+
digits = load_digits()
|
|
36
|
+
X = digits.images.astype("float32") / 16.0
|
|
37
|
+
y = digits.target
|
|
38
|
+
class_names = [str(i) for i in range(10)]
|
|
39
|
+
|
|
40
|
+
X = X[..., np.newaxis] # (samples, height, width, 1)
|
|
41
|
+
print("Dataset shape:", X.shape)
|
|
42
|
+
|
|
43
|
+
n_clusters = int(input(f"Number of clusters (Enter for {len(class_names)}): ") or len(class_names))
|
|
44
|
+
|
|
45
|
+
# 2. Pretext task: exemplar learning
|
|
46
|
+
# Each chosen image becomes its own "class"; the CNN learns to recognise
|
|
47
|
+
# noisy / shifted views of it, which teaches it useful features without labels.
|
|
48
|
+
NUM_EXEMPLARS = min(100, len(X))
|
|
49
|
+
VIEWS = 8
|
|
50
|
+
|
|
51
|
+
chosen = np.random.choice(len(X), NUM_EXEMPLARS, replace=False)
|
|
52
|
+
views, view_labels = [], []
|
|
53
|
+
for i, idx in enumerate(chosen):
|
|
54
|
+
for v in range(VIEWS):
|
|
55
|
+
img = X[idx].copy()
|
|
56
|
+
if v > 0:
|
|
57
|
+
img = np.roll(img, shift=np.random.randint(-1, 2), axis=np.random.randint(0, 2))
|
|
58
|
+
img = np.clip(img + np.random.normal(0, 0.05, img.shape), 0, 1)
|
|
59
|
+
views.append(img)
|
|
60
|
+
view_labels.append(i)
|
|
61
|
+
views = np.array(views, dtype="float32")
|
|
62
|
+
view_labels = np.array(view_labels)
|
|
63
|
+
print("Exemplar training samples:", len(views))
|
|
64
|
+
|
|
65
|
+
# 3. Exemplar CNN
|
|
66
|
+
inputs = Input(shape=X.shape[1:])
|
|
67
|
+
x = Conv2D(16, 3, activation="relu", padding="same")(inputs)
|
|
68
|
+
x = MaxPooling2D()(x)
|
|
69
|
+
x = Conv2D(32, 3, activation="relu", padding="same")(x)
|
|
70
|
+
x = MaxPooling2D()(x)
|
|
71
|
+
x = Flatten()(x)
|
|
72
|
+
features = Dense(64, activation="relu", name="features")(x)
|
|
73
|
+
outputs = Dense(NUM_EXEMPLARS, activation="softmax")(features)
|
|
74
|
+
|
|
75
|
+
exemplar_cnn = Model(inputs, outputs)
|
|
76
|
+
exemplar_cnn.compile(optimizer="adam", loss="sparse_categorical_crossentropy", metrics=["accuracy"])
|
|
77
|
+
history = exemplar_cnn.fit(views, view_labels, epochs=30, batch_size=32, shuffle=True, verbose=1)
|
|
78
|
+
|
|
79
|
+
# 4. Extract learned features and cluster them
|
|
80
|
+
feature_extractor = Model(inputs, features)
|
|
81
|
+
learned = feature_extractor.predict(X, verbose=0)
|
|
82
|
+
learned = normalize(StandardScaler().fit_transform(learned)) # scale features before clustering
|
|
83
|
+
print("Extracted feature shape:", learned.shape)
|
|
84
|
+
|
|
85
|
+
clusters = KMeans(n_clusters=n_clusters, n_init=10, random_state=42).fit_predict(learned)
|
|
86
|
+
|
|
87
|
+
# 5. Evaluate (true labels used only here)
|
|
88
|
+
print(f"\nAdjusted Rand Index (ARI): {adjusted_rand_score(y, clusters):.4f}")
|
|
89
|
+
print(f"Normalized Mutual Information (NMI): {normalized_mutual_info_score(y, clusters):.4f}")
|
|
90
|
+
|
|
91
|
+
print("\nMost common actual classes in each cluster:")
|
|
92
|
+
for c in range(n_clusters):
|
|
93
|
+
counts = np.bincount(y[clusters == c], minlength=len(class_names))
|
|
94
|
+
top = np.argsort(counts)[::-1][:3]
|
|
95
|
+
print(f"Cluster {c}:", [(class_names[t], int(counts[t])) for t in top if counts[t] > 0])
|
|
96
|
+
|
|
97
|
+
# 6. Plot pretext loss and sample images from each cluster
|
|
98
|
+
plt.figure(figsize=(7, 4))
|
|
99
|
+
plt.plot(history.history["loss"], marker="o")
|
|
100
|
+
plt.title("Exemplar CNN Training Loss")
|
|
101
|
+
plt.xlabel("Epoch")
|
|
102
|
+
plt.ylabel("Loss")
|
|
103
|
+
plt.grid(True)
|
|
104
|
+
plt.show()
|
|
105
|
+
|
|
106
|
+
per_row = 6
|
|
107
|
+
fig, axes = plt.subplots(n_clusters, per_row, figsize=(per_row, n_clusters))
|
|
108
|
+
axes = np.array(axes).reshape(n_clusters, per_row)
|
|
109
|
+
for c in range(n_clusters):
|
|
110
|
+
members = np.where(clusters == c)[0][:per_row]
|
|
111
|
+
for j in range(per_row):
|
|
112
|
+
ax = axes[c, j]
|
|
113
|
+
ax.axis("off")
|
|
114
|
+
if j < len(members):
|
|
115
|
+
ax.imshow(X[members[j]].squeeze(), cmap="gray")
|
|
116
|
+
axes[c, 0].set_title(f"C{c}", fontsize=8, loc="left")
|
|
117
|
+
plt.suptitle("Sample images in each cluster")
|
|
118
|
+
plt.tight_layout()
|
|
119
|
+
plt.show()
|
{libz-0.4 → libz-0.5}/README.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{libz-0.4 → libz-0.5}/setup.cfg
RENAMED
|
File without changes
|