diff --git a/web/apps/photos/src/services/machineLearning/clusteringService.ts b/web/apps/photos/src/services/machineLearning/clusteringService.ts deleted file mode 100644 index 32c25f698..000000000 --- a/web/apps/photos/src/services/machineLearning/clusteringService.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { DBSCAN, KMEANS, OPTICS } from "density-clustering"; -import { Hdbscan } from "hdbscan"; -import { HdbscanInput } from "hdbscan/dist/types"; -import { - ClusteringConfig, - ClusteringInput, - ClusteringMethod, - ClusteringResults, - HdbscanResults, - Versioned, -} from "services/ml/types"; - -class ClusteringService { - private dbscan: DBSCAN; - private optics: OPTICS; - private kmeans: KMEANS; - - constructor() { - this.dbscan = new DBSCAN(); - this.optics = new OPTICS(); - this.kmeans = new KMEANS(); - } - - public clusterUsingDBSCAN( - dataset: Array>, - epsilon: number = 1.0, - minPts: number = 2, - ): ClusteringResults { - // log.info("distanceFunction", DBSCAN._); - const clusters = this.dbscan.run(dataset, epsilon, minPts); - const noise = this.dbscan.noise; - return { clusters, noise }; - } - - public clusterUsingOPTICS( - dataset: Array>, - epsilon: number = 1.0, - minPts: number = 2, - ) { - const clusters = this.optics.run(dataset, epsilon, minPts); - return { clusters, noise: [] }; - } - - public clusterUsingKMEANS( - dataset: Array>, - numClusters: number = 5, - ) { - const clusters = this.kmeans.run(dataset, numClusters); - return { clusters, noise: [] }; - } - - public clusterUsingHdbscan(hdbscanInput: HdbscanInput): HdbscanResults { - if (hdbscanInput.input.length < 10) { - throw Error("too few samples to run Hdbscan"); - } - - const hdbscan = new Hdbscan(hdbscanInput); - const clusters = hdbscan.getClusters(); - const noise = hdbscan.getNoise(); - const debugInfo = hdbscan.getDebugInfo(); - - return { clusters, noise, debugInfo }; - } - - public cluster( - method: Versioned, - input: ClusteringInput, - config: ClusteringConfig, - ) { - if (method.value === "Hdbscan") { - return this.clusterUsingHdbscan({ - input, - minClusterSize: config.minClusterSize, - debug: config.generateDebugInfo, - }); - } else if (method.value === "Dbscan") { - return this.clusterUsingDBSCAN( - input, - config.maxDistanceInsideCluster, - config.minClusterSize, - ); - } else { - throw Error("Unknown clustering method: " + method.value); - } - } -} - -export default ClusteringService; diff --git a/web/apps/photos/src/services/machineLearning/dbscanClusteringService.ts b/web/apps/photos/src/services/machineLearning/dbscanClusteringService.ts deleted file mode 100644 index 57d181de4..000000000 --- a/web/apps/photos/src/services/machineLearning/dbscanClusteringService.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { DBSCAN } from "density-clustering"; -import { - ClusteringConfig, - ClusteringInput, - ClusteringMethod, - ClusteringService, - HdbscanResults, - Versioned, -} from "services/ml/types"; - -class DbscanClusteringService implements ClusteringService { - public method: Versioned; - - constructor() { - this.method = { - value: "Dbscan", - version: 1, - }; - } - - public async cluster( - input: ClusteringInput, - config: ClusteringConfig, - ): Promise { - // log.info('Clustering input: ', input); - const dbscan = new DBSCAN(); - const clusters = dbscan.run( - input, - config.clusterSelectionEpsilon, - config.minClusterSize, - ); - const noise = dbscan.noise; - return { clusters, noise }; - } -} - -export default new DbscanClusteringService(); diff --git a/web/apps/photos/src/services/machineLearning/faceService.ts b/web/apps/photos/src/services/machineLearning/faceService.ts index a8957d4b2..c7802a08c 100644 --- a/web/apps/photos/src/services/machineLearning/faceService.ts +++ b/web/apps/photos/src/services/machineLearning/faceService.ts @@ -10,7 +10,6 @@ import { type Versioned, } from "services/ml/types"; import { imageBitmapToBlob, warpAffineFloat32List } from "utils/image"; -import { DEFAULT_ML_SYNC_CONFIG } from "./machineLearningService"; import ReaderService, { fetchImageBitmap, getFaceId, @@ -256,7 +255,6 @@ class FaceService { syncContext.mlLibraryData.faceClusteringResults = await syncContext.faceClusteringService.cluster( allFaces.map((f) => Array.from(f.embedding)), - DEFAULT_ML_SYNC_CONFIG.faceClustering, ); syncContext.mlLibraryData.faceClusteringMethod = syncContext.faceClusteringService.method; diff --git a/web/apps/photos/src/services/machineLearning/hdbscanClusteringService.ts b/web/apps/photos/src/services/machineLearning/hdbscanClusteringService.ts index bf39cd530..f6ea090d8 100644 --- a/web/apps/photos/src/services/machineLearning/hdbscanClusteringService.ts +++ b/web/apps/photos/src/services/machineLearning/hdbscanClusteringService.ts @@ -1,6 +1,5 @@ import { Hdbscan } from "hdbscan"; import { - ClusteringConfig, ClusteringInput, ClusteringMethod, ClusteringService, @@ -18,10 +17,7 @@ class HdbscanClusteringService implements ClusteringService { }; } - public async cluster( - input: ClusteringInput, - config: ClusteringConfig, - ): Promise { + public async cluster(input: ClusteringInput): Promise { // log.info('Clustering input: ', input); const hdbscan = new Hdbscan({ input, diff --git a/web/apps/photos/src/services/ml/types.ts b/web/apps/photos/src/services/ml/types.ts index a5e97098c..e6360dc8b 100644 --- a/web/apps/photos/src/services/ml/types.ts +++ b/web/apps/photos/src/services/ml/types.ts @@ -175,8 +175,6 @@ export interface FaceEmbeddingConfig { generateTsne?: boolean; } -export interface FaceClusteringConfig extends ClusteringConfig {} - export declare type TSNEMetric = "euclidean" | "manhattan"; export interface TSNEConfig { @@ -197,7 +195,7 @@ export interface MLSyncConfig { faceAlignment: FaceAlignmentConfig; blurDetection: BlurDetectionConfig; faceEmbedding: FaceEmbeddingConfig; - faceClustering: FaceClusteringConfig; + faceClustering: any; mlVersion: number; } @@ -294,21 +292,7 @@ export interface BlurDetectionService { export interface ClusteringService { method: Versioned; - cluster( - input: ClusteringInput, - config: ClusteringConfig, - ): Promise; -} - -export interface ClusteringConfig { - method: ClusteringMethod; - minClusterSize: number; - minSamples?: number; - clusterSelectionEpsilon?: number; - clusterSelectionMethod?: "eom" | "leaf"; - maxDistanceInsideCluster?: number; - minInputSize?: number; - generateDebugInfo?: boolean; + cluster(input: ClusteringInput): Promise; } export declare type ClusteringInput = Array>;