Added MPPCosineSimilarity
This commit is contained in:
		
							parent
							
								
									bd507b2d7b
								
							
						
					
					
						commit
						84e1c93ffb
					
				
							
								
								
									
										33
									
								
								mediapipe/tasks/ios/components/utils/BUILD
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								mediapipe/tasks/ios/components/utils/BUILD
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,33 @@
 | 
				
			||||||
 | 
					# Copyright 2023 The MediaPipe Authors. All Rights Reserved.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# 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
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#      http://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.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package(default_visibility = ["//mediapipe/tasks:internal"])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					licenses(["notice"])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					objc_library(
 | 
				
			||||||
 | 
					    name = "MPPCosineSimilarity",
 | 
				
			||||||
 | 
					    srcs = ["sources/MPPCosineSimilarity.mm"],
 | 
				
			||||||
 | 
					    hdrs = ["sources/MPPCosineSimilarity.h"],
 | 
				
			||||||
 | 
					    copts = [
 | 
				
			||||||
 | 
					        "-ObjC++",
 | 
				
			||||||
 | 
					        "-std=c++17",
 | 
				
			||||||
 | 
					        "-x objective-c++",
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    deps = [
 | 
				
			||||||
 | 
					        "//mediapipe/tasks/ios/common:MPPCommon",
 | 
				
			||||||
 | 
					        "//mediapipe/tasks/ios/common/utils:MPPCommonUtils",
 | 
				
			||||||
 | 
					        "//mediapipe/tasks/ios/components/containers:MPPEmbedding",
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,48 @@
 | 
				
			||||||
 | 
					// Copyright 2022 The MediaPipe Authors. All Rights Reserved.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// 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
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//      http://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.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#import <Foundation/Foundation.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#import "mediapipe/tasks/ios/components/containers/sources/MPPEmbedding.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NS_ASSUME_NONNULL_BEGIN
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Utility class for computing cosine similarity between `MPPEmbedding` objects. */
 | 
				
			||||||
 | 
					NS_SWIFT_NAME(CosineSimilarity)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@interface MPPCosineSimilarity : NSObject <NSCopying>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- (instancetype)init NS_UNAVAILABLE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					+ (instancetype)new NS_UNAVAILABLE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Utility function to compute[cosine similarity](https://en.wikipedia.org/wiki/Cosine_similarity)
 | 
				
			||||||
 | 
					 * between two `MPPEmbedding` objects.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @param embedding1 One of the two `MPPEmbedding`s between whom cosine similarity is to be
 | 
				
			||||||
 | 
					 * computed.
 | 
				
			||||||
 | 
					 * @param embedding2 One of the two `MPPEmbedding`s between whom cosine similarity is to be
 | 
				
			||||||
 | 
					 * computed.
 | 
				
			||||||
 | 
					 * @param error An optional error parameter populated when there is an error in calculating cosine
 | 
				
			||||||
 | 
					 * similarity between two embeddings.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @return An `NSNumber` which holds the cosine similarity of type `double`.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					+ (nullable NSNumber *)computeBetweenEmbedding1:(MPPEmbedding *)embedding1
 | 
				
			||||||
 | 
					                                  andEmbedding2:(MPPEmbedding *)embedding2
 | 
				
			||||||
 | 
					                                          error:(NSError **)error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NS_ASSUME_NONNULL_END
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,89 @@
 | 
				
			||||||
 | 
					// Copyright 2022 The MediaPipe Authors. All Rights Reserved.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// 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
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//      http://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.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#import "mediapipe/tasks/ios/components/utils/sources/MPPCosineSimilarity.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#import "mediapipe/tasks/ios/common/sources/MPPCommon.h"
 | 
				
			||||||
 | 
					#import "mediapipe/tasks/ios/common/utils/sources/MPPCommonUtils.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <math.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@implementation MPPCosineSimilarity
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					+ (nullable NSNumber *)computeBetweenVector1:(NSArray<NSNumber *> *)u
 | 
				
			||||||
 | 
					                                  andVector2:(NSArray<NSNumber *> *)v
 | 
				
			||||||
 | 
					                                     isFloat:(BOOL)isFloat
 | 
				
			||||||
 | 
					                                       error:(NSError **)error {
 | 
				
			||||||
 | 
					  if (u.count != v.count) {
 | 
				
			||||||
 | 
					    [MPPCommonUtils
 | 
				
			||||||
 | 
					        createCustomError:error
 | 
				
			||||||
 | 
					                 withCode:MPPTasksErrorCodeInvalidArgumentError
 | 
				
			||||||
 | 
					              description:[NSString stringWithFormat:@"Cannot compute cosine similarity between "
 | 
				
			||||||
 | 
					                                                     @"embeddings of different sizes (%d vs %d)",
 | 
				
			||||||
 | 
					                                                     u.count, v.count]];
 | 
				
			||||||
 | 
					    return nil;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  __block double dotProduct = 0.0;
 | 
				
			||||||
 | 
					  __block double normU = 0.0;
 | 
				
			||||||
 | 
					  __block double normV = 0.0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [u enumerateObjectsUsingBlock:^(NSNumber *num, NSUInteger idx, BOOL *stop) {
 | 
				
			||||||
 | 
					    double uVal = 0.0;
 | 
				
			||||||
 | 
					    double vVal = 0.0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (isFloat) {
 | 
				
			||||||
 | 
					      uVal = num.floatValue;
 | 
				
			||||||
 | 
					      vVal = v[idx].floatValue;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      uVal = num.charValue;
 | 
				
			||||||
 | 
					      vVal = v[idx].charValue;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dotProduct += uVal * vVal;
 | 
				
			||||||
 | 
					    normU += uVal * uVal;
 | 
				
			||||||
 | 
					    normV += vVal * vVal;
 | 
				
			||||||
 | 
					  }];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return [NSNumber numberWithDouble:dotProduct / sqrt(normU * normV)];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					+ (nullable NSNumber *)computeBetweenEmbedding1:(MPPEmbedding *)embedding1
 | 
				
			||||||
 | 
					                                  andEmbedding2:(MPPEmbedding *)embedding2
 | 
				
			||||||
 | 
					                                          error:(NSError **)error {
 | 
				
			||||||
 | 
					  BOOL isFloat;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (embedding1.floatEmbedding && embedding2.floatEmbedding) {
 | 
				
			||||||
 | 
					    return [MPPCosineSimilarity computeBetweenVector1:embedding1.floatEmbedding
 | 
				
			||||||
 | 
					                                           andVector2:embedding2.floatEmbedding
 | 
				
			||||||
 | 
					                                              isFloat:YES
 | 
				
			||||||
 | 
					                                                error:error];
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (embedding1.quantizedEmbedding && embedding2.quantizedEmbedding) {
 | 
				
			||||||
 | 
					    return [MPPCosineSimilarity computeBetweenVector1:embedding1.quantizedEmbedding
 | 
				
			||||||
 | 
					                                           andVector2:embedding2.quantizedEmbedding
 | 
				
			||||||
 | 
					                                              isFloat:NO
 | 
				
			||||||
 | 
					                                                error:error];
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [MPPCommonUtils
 | 
				
			||||||
 | 
					      createCustomError:error
 | 
				
			||||||
 | 
					               withCode:MPPTasksErrorCodeInvalidArgumentError
 | 
				
			||||||
 | 
					            description:
 | 
				
			||||||
 | 
					                @"Cannot compute cosine similarity between quantized and float embeddings."];
 | 
				
			||||||
 | 
					  return nil;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@end
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user