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