Robotics with GPU computing

Overview

Robotics with GPU computing

Build Status PyPI version PyPI - Python Version Downloads xscode

Buy Me A Coffee

Cupoch is a library that implements rapid 3D data processing for robotics using CUDA.

The goal of this library is to implement fast 3D data computation in robot systems. For example, it has applications in SLAM, collision avoidance, path planning and tracking. This repository is based on Open3D.

Core Features

Installation

This library is packaged under 64 Bit Ubuntu Linux 18.04 and CUDA 11.2. You can install cupoch using pip.

pip install cupoch

Or install cupoch from source.

git clone https://github.com/neka-nat/cupoch.git --recurse
cd cupoch
mkdir build
cd build
cmake ..; make install-pip-package -j

Installation for Jetson Nano

You can also install cupoch using pip on Jetson Nano. Please set up Jetson using jetpack and install some packages with apt.

sudo apt-get install libxinerama-dev libxcursor-dev libglu1-mesa-dev
pip3 install cupoch

Or you can compile it from source. Update your version of cmake if necessary.

wget https://github.com/Kitware/CMake/releases/download/v3.16.3/cmake-3.16.3.tar.gz
tar zxvf cmake-3.16.3.tar.gz
cd cmake-3.16.3
./bootstrap -- -DCMAKE_USE_OPENSSL=OFF
make && sudo make install
cd ..
git clone https://github.com/neka-nat/cupoch.git --recurse
cd cupoch/
mkdir build
cd build/
export PATH=/usr/local/cuda/bin:$PATH
cmake -DBUILD_GLEW=ON -DBUILD_GLFW=ON -DBUILD_PNG=ON -DBUILD_JSONCPP=ON ..
sudo make install-pip-package

Results

The figure shows Cupoch's point cloud algorithms speedup over Open3D. The environment tested on has the following specs:

  • Intel Core i7-7700HQ CPU
  • Nvidia GTX1070 GPU
  • OMP_NUM_THREAD=1

You can get the result by running the example script in your environment.

cd examples/python/basic
python benchmarks.py

speedup

Visual odometry with intel realsense D435

vo

Occupancy grid with intel realsense D435

og

Kinect fusion with intel realsense D435

kf

Stereo matching

sm

Fast Global Registration

fgr

Point cloud from laser scan

fgr

Collision detection for 2 voxel grids

col

Drone Path planning

dp

Visual odometry with ROS + D435

This demo works in the following environment.

  • ROS melodic
  • Python2.7
# Launch roscore and rviz in the other terminals.
cd examples/python/ros
python realsense_rgbd_odometry_node.py

vo

Visualization

Point Cloud Triangle Mesh Kinematics
Voxel Grid Occupancy Grid Distance Transform
Graph Image

References

Comments
  • KDTreeFlann

    KDTreeFlann

    Hello, when I use EstimateNormals and ComputeFPFHFeature, I found that geometry::KDTreeFlann kdtree (that is, building kdtree) takes a lot of time. I want to update it here. Do you have any suggestions for improvement?

    opened by xiaopeige 12
  • Memory error with realsense occupancygrid

    Memory error with realsense occupancygrid

    Hi, I am trying to use cupoch to mapping with L515 Lidar sensor.

    I am using python script 'realsense_occupancygrid_viewer.py'

    My goal is using cupoch in Jetson Nano Developer Kit but now I am working in laptop.

    My hardware environment (DELL XPS Laptop) is

    • GTX 1050 Ti with 4042MiB memory
    • nvidia driver 460.32.03
    • CUDA Version 11.2

    At first, the default voxel_size and resolution seems too high (ocgd = cph.geometry.OccupancyGrid(0.05, 512)). With default configuration, I got error

    MemoryError: std::bad_alloc: RMM failure at:/home/runner/work/cupoch/cupoch/third_party/rmm/includermm/mr/device/pool_memory_resource.hpp:188: Maximum pool size exceeded.
    

    So I changed it to ocgd = cph.geometry.OccupancyGrid(0.1, 128).

    The script looks working but memory-usage(check with nvidia-smi) surge very quickly and got same memory error in temp = temp.voxel_down_sample(0.03)

    I could not found memory related parameters. Can you suggest any solution to solve the problem?

    Thank you.

    question 
    opened by ldg810 10
  • [BUG] performance in ros callback context.

    [BUG] performance in ros callback context.

    As #60 did, I gave more tests on performance.

    The passfilter function costs 0.096551ms to filter 119978 points to 5510.

    image

    But this output is in a simple execution context, you can find the code in #60

    When the function run in ros callback context, the performance becomes really low, as 0.670853ms

    image

    Any ideas about the reason?

    enhancement 
    opened by ZhenshengLee 9
  • When will windows be supported?

    When will windows be supported?

    Hi everyone,

    I am so greatly to hear that the libray was able to process 3D point cloud data using CUDA. Furthermore, cupoch is based on the functionality of Open3D.

    From this issue: https://github.com/neka-nat/cupoch/issues/3, I know that the libray didn't support either MINGW or MSVC on windows.

    However, my app developed with MSVC and ran on windows. Up to now, I use Open3D to implement my requirements on CPU yet. I'm very anxious to speed up my app by running on GPU.

    When will windows be supported?

    enhancement 
    opened by caibf 9
  • fatal error: cupoch/cupoch.h: No such file or directory

    fatal error: cupoch/cupoch.h: No such file or directory

    I have installed Cupoch via pip as described in the docs. The Python bindings seems to work, however, when building the cpp examples I get the following error:

    image

    In the examples subfolder, I ran

    mkdir build
    cd build
    cmake ..
    make
    

    This was tested on an Nvidia Jetson Nano

    opened by mvanlobensels 7
  • [QST]About the best practice of memory copy.

    [QST]About the best practice of memory copy.

    Hi everyone,

    I am trying to find the best way to copy points between host and device, and I found several methods in cupoch. So which method is of best performance(in time comsuming)

    thrust copy constructable function

    may not be the best

    // d2h
    auto pointcloud_points_host = pointcloud->GetPoints();
    // h2d
    void PointCloud::SetPoints(const thrust::host_vector<Eigen::Vector3f> &points) {
        points_ = points;
    }
    

    memcpy with thrust raw pointer

    in src/cupoch/io/class_io/pointcloud_io.cu

    void HostPointCloud::FromDevice(const geometry::PointCloud& pointcloud) {
        points_.resize(pointcloud.points_.size());
        normals_.resize(pointcloud.normals_.size());
        colors_.resize(pointcloud.colors_.size());
        cudaSafeCall(cudaMemcpy(points_.data(), thrust::raw_pointer_cast(pointcloud.points_.data()),
                                points_.size() * sizeof(Eigen::Vector3f), cudaMemcpyDeviceToHost));
        cudaSafeCall(cudaMemcpy(normals_.data(), thrust::raw_pointer_cast(pointcloud.normals_.data()),
                                normals_.size() * sizeof(Eigen::Vector3f), cudaMemcpyDeviceToHost));
        cudaSafeCall(cudaMemcpy(colors_.data(), thrust::raw_pointer_cast(pointcloud.colors_.data()),
                                colors_.size() * sizeof(Eigen::Vector3f), cudaMemcpyDeviceToHost));
    }
    
    void HostPointCloud::ToDevice(geometry::PointCloud& pointcloud) const {
        pointcloud.points_.resize(points_.size());
        pointcloud.normals_.resize(normals_.size());
        pointcloud.colors_.resize(colors_.size());
        cudaSafeCall(cudaMemcpy(thrust::raw_pointer_cast(pointcloud.points_.data()), points_.data(),
                                points_.size() * sizeof(Eigen::Vector3f), cudaMemcpyHostToDevice));
        cudaSafeCall(cudaMemcpy(thrust::raw_pointer_cast(pointcloud.normals_.data()), normals_.data(),
                                normals_.size() * sizeof(Eigen::Vector3f), cudaMemcpyHostToDevice));
        cudaSafeCall(cudaMemcpy(thrust::raw_pointer_cast(pointcloud.colors_.data()), colors_.data(),
                                colors_.size() * sizeof(Eigen::Vector3f), cudaMemcpyHostToDevice));
    }
    

    thrust::copy (even with cudastream)

    src/cupoch/geometry/down_sample.cu

    thrust::copy(utility::exec_policy(utility::GetStream(0))
                             ->on(utility::GetStream(0)),
                     range_points.begin(), range_points.end(),
                     output->points_.begin());
        if (has_normals) {
            thrust::strided_range<
                    utility::device_vector<Eigen::Vector3f>::const_iterator>
                    range_normals(normals_.begin(), normals_.end(), every_k_points);
            thrust::copy(utility::exec_policy(utility::GetStream(1))
                                 ->on(utility::GetStream(1)),
                         range_normals.begin(), range_normals.end(),
                         output->normals_.begin());
        }
        if (has_colors) {
            thrust::strided_range<
                    utility::device_vector<Eigen::Vector3f>::const_iterator>
                    range_colors(colors_.begin(), colors_.end(), every_k_points);
            thrust::copy(utility::exec_policy(utility::GetStream(2))
                                 ->on(utility::GetStream(2)),
                         range_colors.begin(), range_colors.end(),
                         output->colors_.begin());
        }
        cudaSafeCall(cudaDeviceSynchronize());
    
    enhancement 
    opened by ZhenshengLee 7
  • Building from source error with CUDA & eigen3

    Building from source error with CUDA & eigen3

    Hello @neka-nat,

    A huge thanks for Cupoch

    But im facing issue while building from source

    system config

    Nvidia geforce 1650 cuda toolkit 10.2 ubuntu 19.10 inbuilt Eigen : eigen 3.3.7

    I tried with both eigen3 3rdparty and inbuilt version using cmake -DBUILD_EIGEN3=OFF and cmake -DBUILD_EIGEN3=ON

    the make make install-pip-package -j is getting killed

    few error snippets are

    /home/shankar/3D projects/cupoch/cupoch/src/cupoch/geometry/boundingvolume.cu(26): error: identifier "Eigen::MatrixBase< ::Eigen::Matrix<float, (int)3, (int)3, (int)0, (int)3, (int)3> > ::determinant const" is undefined in device code

    36 errors detected in the compilation of "/tmp/tmpxft_00007184_00000000-6_boundingvolume.cpp1.ii". CMake Error at cupoch_geometry_generated_boundingvolume.cu.o.cmake:280 (message): Error generating file /home/shankar/3D projects/cupoch/cupoch/build/src/cupoch/geometry/CMakeFiles/cupoch_geometry.dir//./cupoch_geometry_generated_boundingvolume.cu.o

    make[1]: *** [CMakeFiles/Makefile2:755: src/cupoch/geometry/CMakeFiles/cupoch_geometry.dir/all] Error 2 make: *** [Makefile:130: all] Error 2

    opened by devshank3 7
  • Is Cupoch Windows MSVC GPU ready to work?

    Is Cupoch Windows MSVC GPU ready to work?

    Hello,

    I tried to test Cupoch on Windows 10.

    1. Build with VS2019 --> no problem.
    2. Test normal calculation with the same 18519 points PCD --> Open3D needs 10ms, Cupoch needs 52 ms

    Here is the code

    pcd->EstimateNormals(open3d::geometry::KDTreeSearchParamHybrid(radius_normal, MAX_NN));
    pcd_gpu->EstimateNormals(cupoch::geometry::KDTreeSearchParamHybrid(radius_normal, MAX_NN));
    

    I guess that the calculation was not run on GPU. But how to make sure it is run on GPU? I already had this line in my code

    cupoch::utility::InitializeAllocator();

    question 
    opened by 1939938853 6
  • MemoryError cph.initialize_allocator(cph.PoolAllocation, 1000000000)

    MemoryError cph.initialize_allocator(cph.PoolAllocation, 1000000000)

    All python examples complain about cph.PoolAllocation. Has anyone else seen that? cuda toolkit 11.6 NVIDIA-SMI 510.60.02 Driver Version: 510.60.02 CUDA Version: 11.6
    There is plenty of GPU mem available. The 1G fits in easily. I can reduce the size heavily and same issue

    traceback (most recent call last): File "basic/benchmarks3.py", line 5, in cph.initialize_allocator(cph.PoolAllocation, 1000000000) MemoryError: std::bad_alloc: RMM failure at:/home/adolf/cupoch/third_party/rmm/include/rmm/mr/device/pool_memory_resource.hpp:179: Maximum pool size exceeded

    opened by ducktrA 5
  • DBSCAN slow than cpu method

    DBSCAN slow than cpu method

    Test using a small point cloud with 15million points, and it takes extremely long to process. The gpu is nvidia a600 with 48gb memory. Cuda version is 11.2. Is cuml used in the library? It suffers the batch shrinking problem

    [2021-10-12 12:00:22.331] [debug] Read geometry::PointCloud: 15636915 vertices.

    [2021-10-12 12:00:22.340] [debug] [RemoveNoneFinitePoints] 15636915 nan points have been removed. (15636915, 3) (15636915, 3) block_0 has 15636915 points | ID | GPU | MEM |

    | 0 | 18% | 2% | [2021-10-12 12:00:22.798] [debug] Precompute Neighbours Precompute Neighbours[================> ] 40%

    invalid 
    opened by Xuechun-Hu 5
  • [error] [CreateToPointCloud2Msg] Width and Step sizes must be greater than 0

    [error] [CreateToPointCloud2Msg] Width and Step sizes must be greater than 0

    Hi @neka-nat,

    I have created the following simple ROS node to convert from a PointCloud2 to a Cupoch point cloud back to PointCloud2. This is based on your latest python example to convert from Cupoch to PointCloud2, however using the unchanged pointcloud does not work:

    class PointCloudFilter:
    
        def __init__(self):
            self._point_cloud_sub = rospy.Subscriber('/camera1/depth/color/points', PointCloud2, self.point_cloud_callback)
            self._filtered_point_cloud_pub = rospy.Publisher('/camera1/depth/color/filtered', PointCloud2, queue_size=1)
    
        def point_cloud_callback(self, msg):
            pointcloud = cph.io.create_from_pointcloud2_msg(msg.data, cph.io.PointCloud2MsgInfo.default(msg.width, msg.point_step))
    
            data, info = cph.io.create_to_pointcloud2_msg(pointcloud)
    
    if __name__ == '__main__':
        rospy.init_node('point_cloud_filter')
        filter = PointCloudFilter()
        rospy.spin()
    

    However, this results in the following error: [error] [CreateToPointCloud2Msg] Width and Step sizes must be greater than 0.

    This is running on my laptop (x86_64), Python 3.6.9, CUDA 11.4. Thank you in advance.

    opened by mvanlobensels 5
  • icp TransformationEstimationPointToPlane yields different result compare to open3d

    icp TransformationEstimationPointToPlane yields different result compare to open3d

    import cupoch as cph
    
    target = cph.io.read_point_cloud("PointCloud_1.ply")
    source = cph.io.read_point_cloud("PointCloud_2.ply")
    
    import numpy as np
    source.estimate_normals(cph.geometry.KDTreeSearchParamRadius(radius=1 * 2, max_nn=30))
    target.estimate_normals(cph.geometry.KDTreeSearchParamRadius(radius=1 * 2, max_nn=30))
    reg_p2p = cph.registration.registration_icp(
        source, target, 0.15,np.identity(4).astype(np.float32),
        estimation_method = cph.registration.TransformationEstimationPointToPlane())
    print(reg_p2p.transformation,reg_p2p.inlier_rmse,reg_p2p.fitness)
    

    result:

    [warning] check_det failed, empty vector will be returned [[ 9.9999994e-01 -2.3211574e-04 3.1052838e-04 -5.6119312e-02] [ 2.3210575e-04 1.0000000e+00 4.1026891e-05 1.5950035e-01] [-3.1053583e-04 -4.0970357e-05 9.9999994e-01 1.3352202e-01] [ 0.0000000e+00 0.0000000e+00 0.0000000e+00 1.0000000e+00]] 0.11659056693315506 0.5279329419136047

    def icp_p2plane(source,target,distance):
        source.estimate_normals(o3d.geometry.KDTreeSearchParamHybrid(radius=1*2,max_nn=30))
        target.estimate_normals(o3d.geometry.KDTreeSearchParamHybrid(radius=1*2,max_nn=30))
        reg_p2p = o3d.pipelines.registration.registration_icp(
            source, target, distance,init = np.identity(4).astype(np.float32),
            estimation_method = o3d.pipelines.registration.TransformationEstimationPointToPlane())
        return reg_p2p
    
    target = o3d.io.read_point_cloud("PointCloud_1.ply")
    source = o3d.io.read_point_cloud("PointCloud_2.ply")
    reg_p2p_cpu = icp_p2plane(source,target,0.15)
    print(reg_p2p_cpu.transformation,reg_p2p_cpu.inlier_rmse,reg_p2p_cpu.fitness)
    

    result: [[ 9.99999876e-01 -1.51703967e-04 4.75125722e-04 -3.06633247e-02] [ 1.51902093e-04 9.99999902e-01 -4.16987856e-04 5.89422629e-01] [-4.75062417e-04 4.17059977e-04 9.99999800e-01 2.32936885e-01] [ 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00]] 0.0851198294781214 0.8659489299658403

    PointCloud_2.ply.zip PointCloud_1.ply.zip

    edit: if i simply use source.estimate_normals(), the results are also different it seems like during icp process, some condition were not considered and then the program breaks and throw halfway output. really appreciate your help.

    opened by funnyvalentine2363 0
  • fastglobalregistration.cu have error

    fastglobalregistration.cu have error

    When I call the fgr algorithm, the prompt crashes here, line 141 in fastglobalregistration.cu thrust::sort(utility::exec_policy(0)->on(0), corres.begin(), corres.end()); and the following error is prompted, 微信图片_20220728110848 How to solve this problem please? thank you!

    bug 
    opened by xiaopeige 0
  • Getting cudaErrorMemoryAllocation out of memory

    Getting cudaErrorMemoryAllocation out of memory

    Hi This library is awesome! Thank you, author. I am working on big-size point clouds (in ply format). I am trying this code (https://github.com/neka-nat/cupoch/blob/master/examples/python/advanced/pointcloud_outlier_removal.py) to filter point cloud noises. On a few MBs or around 1Gbs size point cloud file works like a charm. But when I try on a bigger point cloud file(5GB - approx 97million points) then I after remove_statistical_outlier I am getting cudaErrorMemoryAllocation out of memory.

    cl, ind = voxel_down_pcd.remove_statistical_outlier(nb_neighbors=20, std_ratio=2.0)
    Memory Error: std::bad_alloc: CUDA error at /home/path/cupoch/cupoch/third_party/rmm/include/rmm/mr/device/cuda_memory_resource.hpp:69: cudaErrorMemoryAllocation out of memory
    

    I really wanted to use this library as it is much faster than other alternatives. Can you help me with how to solve this issue? I really appreciate this. Thank you again in advance!! P.S. System: Ubuntu 20.04 RTX3090 24GB I installed cupoch using pip

    opened by quicktwit 6
  • Poisson's surface reconstruction

    Poisson's surface reconstruction

    Hello, Any plans to add Poisson's surface reconstruction that runs on GPU? Currently I am doing everything(registration,cropping etc..) with cupoch gpu, saving the ply file on hardisk and then using open 3d to read the ply file from harddisk and then do the poisons surface reconstruction on cpu with open 3d

    Cupoch having Poisson's surface reconstruction on gpu will be really helpful.

    enhancement 
    opened by nithinpanand 0
  • Redefinition problem of 3rd party lib when use Cupoch side by side with Open3D

    Redefinition problem of 3rd party lib when use Cupoch side by side with Open3D

    Hi,

    I think that in many aspects Cupoch and Open3D are really mutually complementary. But when using both together side by side, there may issue variable redefinition error from the compiler, since both may use the same 3rd party lib in several parts?

    Perhaps, could add some flags in cmake files to deal with it?

    Thanks

    enhancement 
    opened by 1939938853 0
Releases(v0.2.6)
Owner
Shirokuma
Interested in computer vision (Point cloud, GPU computing), robotics and machine learning.
Shirokuma
Code for Contrastive-Geometry Networks for Generalized 3D Pose Transfer

CGTransformer Code for our AAAI 2022 paper "Contrastive-Geometry Transformer network for Generalized 3D Pose Transfer" Contrastive-Geometry Transforme

18 Jun 28, 2022
The Noise Contrastive Estimation for softmax output written in Pytorch

An NCE implementation in pytorch About NCE Noise Contrastive Estimation (NCE) is an approximation method that is used to work around the huge computat

Kaiyu Shi 287 Nov 25, 2022
A very tiny, very simple, and very secure file encryption tool.

Picocrypt is a very tiny (hence "Pico"), very simple, yet very secure file encryption tool. It uses the modern ChaCha20-Poly1305 cipher suite as well

Evan Su 1k Dec 30, 2022
A tool for calculating distortion parameters in coordination complexes.

OctaDist Octahedral distortion calculator: A tool for calculating distortion parameters in coordination complexes. https://octadist.github.io/ Registe

OctaDist 12 Oct 04, 2022
MBPO (paper: When to trust your model: Model-based policy optimization) in offline RL settings

offline-MBPO This repository contains the code of a version of model-based RL algorithm MBPO, which is modified to perform in offline RL settings Pape

LxzGordon 1 Oct 24, 2021
Implementation of ICLR 2020 paper "Revisiting Self-Training for Neural Sequence Generation"

Self-Training for Neural Sequence Generation This repo includes instructions for running noisy self-training algorithms from the following paper: Revi

Junxian He 45 Dec 31, 2022
PyTorch implementation of DeepDream algorithm

neural-dream This is a PyTorch implementation of DeepDream. The code is based on neural-style-pt. Here we DeepDream a photograph of the Golden Gate Br

121 Nov 05, 2022
PyTorch Implementation for AAAI'21 "Do Response Selection Models Really Know What's Next? Utterance Manipulation Strategies for Multi-turn Response Selection"

UMS for Multi-turn Response Selection Implements the model described in the following paper Do Response Selection Models Really Know What's Next? Utte

Taesun Whang 47 Nov 22, 2022
High frequency AI based algorithmic trading module.

Flow Flow is a high frequency algorithmic trading module that uses machine learning to self regulate and self optimize for maximum return. The current

59 Dec 14, 2022
Pytorch implementation of TailCalibX : Feature Generation for Long-tail Classification

TailCalibX : Feature Generation for Long-tail Classification by Rahul Vigneswaran, Marc T. Law, Vineeth N. Balasubramanian, Makarand Tapaswi [arXiv] [

Rahul Vigneswaran 34 Jan 02, 2023
QuadTree Attention for Vision Transformers (ICLR2022)

This repository contains codes for quadtree attention. This repo contains codes for feature matching, image classficiation, object detection and seman

tangshitao 222 Dec 28, 2022
NeWT: Natural World Tasks

NeWT: Natural World Tasks This repository contains resources for working with the NeWT dataset. ❗ At this time the binary tasks are not publicly avail

Visipedia 26 Oct 18, 2022
Weight estimation in CT by multi atlas techniques

maweight A Python package for multi-atlas based weight estimation for CT images, including segmentation by registration, feature extraction and model

György Kovács 0 Dec 24, 2021
Repository for benchmarking graph neural networks

Benchmarking Graph Neural Networks Updates Nov 2, 2020 Project based on DGL 0.4.2. See the relevant dependencies defined in the environment yml files

NTU Graph Deep Learning Lab 2k Jan 03, 2023
Implementation of the state of the art beat-detection, downbeat-detection and tempo-estimation model

The ISMIR 2020 Beat Detection, Downbeat Detection and Tempo Estimation Model Implementation. This is an implementation in TensorFlow to implement the

Koen van den Brink 1 Nov 12, 2021
Official PyTorch implementation of StyleGAN3

Modified StyleGAN3 Repo Changes Made tied to python 3.7 syntax .jpgs instead of .pngs for training sample seeds to recreate the 1024 training grid wit

Derrick Schultz (he/him) 83 Dec 15, 2022
a baseline to practice

ccks2021_track3_baseline a baseline to practice 路径可能会有问题,自己改改 torch==1.7.1 pyhton==3.7.1 transformers==4.7.0 cuda==11.0 this is a baseline, you can fi

45 Nov 23, 2022
This repository contains the code for EMNLP-2021 paper "Word-Level Coreference Resolution"

Word-Level Coreference Resolution This is a repository with the code to reproduce the experiments described in the paper of the same name, which was a

79 Dec 27, 2022
Weakly-Supervised Semantic Segmentation Network with Deep Seeded Region Growing (CVPR 2018).

Weakly-Supervised Semantic Segmentation Network with Deep Seeded Region Growing (CVPR2018) By Zilong Huang, Xinggang Wang, Jiasi Wang, Wenyu Liu and J

Zilong Huang 245 Dec 13, 2022
PyTorch Code for the paper "VSE++: Improving Visual-Semantic Embeddings with Hard Negatives"

Improving Visual-Semantic Embeddings with Hard Negatives Code for the image-caption retrieval methods from VSE++: Improving Visual-Semantic Embeddings

Fartash Faghri 441 Dec 05, 2022