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