'
13 |
14 | hr_faded: '
'
15 | hr_shaded: '
'
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright 2018 Finn.no / Joakim Rishaug
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4 |
5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6 |
7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
8 |
--------------------------------------------------------------------------------
/docs/licenses/LICENSE:
--------------------------------------------------------------------------------
1 | /* This license pertains to the docs template, except for the Navgoco jQuery component. */
2 |
3 | The MIT License (MIT)
4 |
5 | Original theme: Copyright (c) 2016 Tom Johnson
6 | Modifications: Copyright (c) 2017 onwards fast.ai, Inc
7 |
8 | Permission is hereby granted, free of charge, to any person obtaining a copy
9 | of this software and associated documentation files (the "Software"), to deal
10 | in the Software without restriction, including without limitation the rights
11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 | copies of the Software, and to permit persons to whom the Software is
13 | furnished to do so, subject to the following conditions:
14 |
15 | The above copyright notice and this permission notice shall be included in all
16 | copies or substantial portions of the Software.
17 |
18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 | SOFTWARE.
25 |
--------------------------------------------------------------------------------
/.github/workflows/main.yml:
--------------------------------------------------------------------------------
1 | name: CI
2 | on: [push]
3 | jobs:
4 | build:
5 | runs-on: ubuntu-latest
6 | steps:
7 | - uses: actions/checkout@v1
8 | - uses: actions/setup-python@v1
9 | with:
10 | python-version: '3.6'
11 | architecture: 'x64'
12 | - name: Install the library
13 | run: |
14 | pip install nbdev jupyter
15 | pip install -e .
16 | - name: Read all notebooks
17 | run: |
18 | nbdev_read_nbs
19 | - name: Check if all notebooks are cleaned
20 | run: |
21 | echo "Check we are starting with clean git checkout"
22 | if [ -n "$(git status -uno -s)" ]; then echo "git status is not clean"; false; fi
23 | echo "Trying to strip out notebooks"
24 | nbdev_clean_nbs
25 | echo "Check that strip out was unnecessary"
26 | git status -s # display the status to see which nbs need cleaning up
27 | if [ -n "$(git status -uno -s)" ]; then echo -e "!!! Detected unstripped out notebooks\n!!!Remember to run nbdev_install_git_hooks"; false; fi
28 | - name: Check if there is no diff library/notebooks
29 | run: |
30 | if [ -n "$(nbdev_diff_nbs)" ]; then echo -e "!!! Detected difference between the notebooks and the library"; false; fi
31 | - name: Run tests
32 | run: |
33 | nbdev_test_nbs
34 |
--------------------------------------------------------------------------------
/docs/feed.xml:
--------------------------------------------------------------------------------
1 | ---
2 | search: exclude
3 | layout: none
4 | ---
5 |
6 |
7 |
8 |
9 | {{ site.title | xml_escape }}
10 | {{ site.description | xml_escape }}
11 | {{ site.url }}/
12 |
13 | {{ site.time | date_to_rfc822 }}
14 | {{ site.time | date_to_rfc822 }}
15 | Jekyll v{{ jekyll.version }}
16 | {% for post in site.posts limit:10 %}
17 | -
18 |
{{ post.title | xml_escape }}
19 | {{ post.content | xml_escape }}
20 | {{ post.date | date_to_rfc822 }}
21 | {{ post.url | prepend: site.url }}
22 | {{ post.url | prepend: site.url }}
23 | {% for tag in post.tags %}
24 | {{ tag | xml_escape }}
25 | {% endfor %}
26 | {% for tag in page.tags %}
27 | {{ cat | xml_escape }}
28 | {% endfor %}
29 |
30 | {% endfor %}
31 |
32 |
33 |
--------------------------------------------------------------------------------
/docs/_config.yml:
--------------------------------------------------------------------------------
1 | repository: NegatioN/online_triplet_loss
2 | output: web
3 | topnav_title: WARP-Pytorch
4 | site_title: WARP-Pytorch
5 | company_name: "Joakim Rishaug"
6 | description: "WARP loss for Pytorch. WSABIE"
7 | # Set to false to disable KaTeX math
8 | use_math: true
9 | # Add Google analytics id if you have one and want to use it here
10 | google_analytics:
11 | # See http://nbdev.fast.ai/search for help with adding Search
12 | google_search:
13 |
14 | host: 127.0.0.1
15 | # the preview server used. Leave as is.
16 | port: 4000
17 | # the port where the preview is rendered.
18 |
19 | exclude:
20 | - .idea/
21 | - .gitignore
22 | - vendor
23 |
24 | exclude: [vendor]
25 |
26 | highlighter: rouge
27 | markdown: kramdown
28 | kramdown:
29 | input: GFM
30 | auto_ids: true
31 | hard_wrap: false
32 | syntax_highlighter: rouge
33 |
34 | collections:
35 | tooltips:
36 | output: false
37 |
38 | defaults:
39 | -
40 | scope:
41 | path: ""
42 | type: "pages"
43 | values:
44 | layout: "page"
45 | comments: true
46 | search: true
47 | sidebar: home_sidebar
48 | topnav: topnav
49 | -
50 | scope:
51 | path: ""
52 | type: "tooltips"
53 | values:
54 | layout: "page"
55 | comments: true
56 | search: true
57 | tooltip: true
58 |
59 | sidebars:
60 | - home_sidebar
61 | permalink: pretty
62 |
63 | theme: jekyll-theme-cayman
64 | baseurl: /WARP-Pytorch/
--------------------------------------------------------------------------------
/docs/_includes/links.html:
--------------------------------------------------------------------------------
1 | {% comment %}Get links from each sidebar, as listed in the _config.yml file under sidebars{% endcomment %}
2 |
3 | {% for sidebar in site.sidebars %}
4 | {% for entry in site.data.sidebars[sidebar].entries %}
5 | {% for folder in entry.folders %}
6 | {% for folderitem in folder.folderitems %}
7 | {% if folderitem.url contains "html#" %}
8 | [{{folderitem.url | remove: "/" }}]: {{folderitem.url | remove: "/"}}
9 | {% else %}
10 | [{{folderitem.url | remove: "/" | remove: ".html"}}]: {{folderitem.url | remove: "/"}}
11 | {% endif %}
12 | {% for subfolders in folderitem.subfolders %}
13 | {% for subfolderitem in subfolders.subfolderitems %}
14 | [{{subfolderitem.url | remove: "/" | remove: ".html"}}]: {{subfolderitem.url | remove: "/"}}
15 | {% endfor %}
16 | {% endfor %}
17 | {% endfor %}
18 | {% endfor %}
19 | {% endfor %}
20 | {% endfor %}
21 |
22 |
23 | {% comment %} Get links from topnav {% endcomment %}
24 |
25 | {% for entry in site.data.topnav.topnav %}
26 | {% for item in entry.items %}
27 | {% if item.external_url == null %}
28 | [{{item.url | remove: "/" | remove: ".html"}}]: {{item.url | remove: "/"}}
29 | {% endif %}
30 | {% endfor %}
31 | {% endfor %}
32 |
33 | {% comment %}Get links from topnav dropdowns {% endcomment %}
34 |
35 | {% for entry in site.data.topnav.topnav_dropdowns %}
36 | {% for folder in entry.folders %}
37 | {% for folderitem in folder.folderitems %}
38 | {% if folderitem.external_url == null %}
39 | [{{folderitem.url | remove: "/" | remove: ".html"}}]: {{folderitem.url | remove: "/"}}
40 | {% endif %}
41 | {% endfor %}
42 | {% endfor %}
43 | {% endfor %}
44 |
45 |
--------------------------------------------------------------------------------
/docs/css/modern-business.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * Start Bootstrap - Modern Business HTML Template (http://startbootstrap.com)
3 | * Code licensed under the Apache License v2.0.
4 | * For details, see http://www.apache.org/licenses/LICENSE-2.0.
5 | */
6 |
7 | /* Global Styles */
8 |
9 | html,
10 | body {
11 | height: 100%;
12 | }
13 |
14 | .img-portfolio {
15 | margin-bottom: 30px;
16 | }
17 |
18 | .img-hover:hover {
19 | opacity: 0.8;
20 | }
21 |
22 | /* Home Page Carousel */
23 |
24 | header.carousel {
25 | height: 50%;
26 | }
27 |
28 | header.carousel .item,
29 | header.carousel .item.active,
30 | header.carousel .carousel-inner {
31 | height: 100%;
32 | }
33 |
34 | header.carousel .fill {
35 | width: 100%;
36 | height: 100%;
37 | background-position: center;
38 | background-size: cover;
39 | }
40 |
41 | /* 404 Page Styles */
42 |
43 | .error-404 {
44 | font-size: 100px;
45 | }
46 |
47 | /* Pricing Page Styles */
48 |
49 | .price {
50 | display: block;
51 | font-size: 50px;
52 | line-height: 50px;
53 | }
54 |
55 | .price sup {
56 | top: -20px;
57 | left: 2px;
58 | font-size: 20px;
59 | }
60 |
61 | .period {
62 | display: block;
63 | font-style: italic;
64 | }
65 |
66 | /* Footer Styles */
67 |
68 | footer {
69 | margin: 50px 0;
70 | }
71 |
72 | /* Responsive Styles */
73 |
74 | @media(max-width:991px) {
75 | .client-img,
76 | .img-related {
77 | margin-bottom: 30px;
78 | }
79 | }
80 |
81 | @media(max-width:767px) {
82 | .img-portfolio {
83 | margin-bottom: 15px;
84 | }
85 |
86 | header.carousel .carousel {
87 | height: 70%;
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/docs/_includes/head_print.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
{% if page.homepage == true %} {{site.homepage_title}} {% elsif page.title %}{{ page.title }}{% endif %} | {{ site.site_title }}
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
23 |
24 |
29 |
--------------------------------------------------------------------------------
/docs/licenses/LICENSE-BSD-NAVGOCO.txt:
--------------------------------------------------------------------------------
1 | /* This license pertains to the Navgoco jQuery component used for the sidebar. */
2 |
3 | Copyright (c) 2013, Christodoulos Tsoulloftas, http://www.komposta.net
4 | All rights reserved.
5 |
6 | Redistribution and use in source and binary forms, with or without modification,
7 | are permitted provided that the following conditions are met:
8 |
9 | * Redistributions of source code must retain the above copyright notice,
10 | this list of conditions and the following disclaimer.
11 | * Redistributions in binary form must reproduce the above copyright notice,
12 | this list of conditions and the following disclaimer in the documentation
13 | and/or other materials provided with the distribution.
14 | * Neither the name of the
nor the names of its
15 | contributors may be used to endorse or promote products derived from this
16 | software without specific prior written permission.
17 |
18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
22 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
23 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 | OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
27 | OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 | .idea/
6 | # C extensions
7 | *.so
8 |
9 | .gitattributes
10 | .gitconfig
11 | # Distribution / packaging
12 | .Python
13 | build/
14 | develop-eggs/
15 | dist/
16 | downloads/
17 | eggs/
18 | .eggs/
19 | lib/
20 | lib64/
21 | parts/
22 | sdist/
23 | var/
24 | wheels/
25 | *.egg-info/
26 | .installed.cfg
27 | *.egg
28 | MANIFEST
29 |
30 | # PyInstaller
31 | # Usually these files are written by a python script from a template
32 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
33 | *.manifest
34 | *.spec
35 |
36 | # Installer logs
37 | pip-log.txt
38 | pip-delete-this-directory.txt
39 |
40 | # Unit test / coverage reports
41 | htmlcov/
42 | .tox/
43 | .coverage
44 | .coverage.*
45 | .cache
46 | nosetests.xml
47 | coverage.xml
48 | *.cover
49 | .hypothesis/
50 | .pytest_cache/
51 |
52 | # Translations
53 | *.mo
54 | *.pot
55 |
56 | # Django stuff:
57 | *.log
58 | local_settings.py
59 | db.sqlite3
60 |
61 | # Flask stuff:
62 | instance/
63 | .webassets-cache
64 |
65 | # Scrapy stuff:
66 | .scrapy
67 |
68 | # Sphinx documentation
69 | docs/_build/
70 |
71 | # PyBuilder
72 | target/
73 |
74 | # Jupyter Notebook
75 | .ipynb_checkpoints
76 |
77 | # pyenv
78 | .python-version
79 |
80 | # celery beat schedule file
81 | celerybeat-schedule
82 |
83 | # SageMath parsed files
84 | *.sage.py
85 |
86 | # Environments
87 | .env
88 | .venv
89 | env/
90 | venv/
91 | ENV/
92 | env.bak/
93 | venv.bak/
94 |
95 | # Spyder project settings
96 | .spyderproject
97 | .spyproject
98 |
99 | # Rope project settings
100 | .ropeproject
101 |
102 | # mkdocs documentation
103 | /site
104 |
105 | # mypy
106 | .mypy_cache/
107 |
--------------------------------------------------------------------------------
/docs/_layouts/page.html:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | ---
4 |
5 |
9 |
10 | {% if page.simple_map == true %}
11 |
12 |
17 |
18 | {% include custom/{{page.map_name}}.html %}
19 |
20 | {% elsif page.complex_map == true %}
21 |
22 |
27 |
28 | {% include custom/{{page.map_name}}.html %}
29 |
30 | {% endif %}
31 |
32 |
33 |
34 | {% if page.summary %}
35 |
{{page.summary}}
36 | {% endif %}
37 |
38 | {% unless page.toc == false %}
39 | {% include toc.html %}
40 | {% endunless %}
41 |
42 |
43 | {% if site.github_editme_path %}
44 |
45 |
Edit me
46 |
47 | {% endif %}
48 |
49 | {{content}}
50 |
51 |
62 |
63 |
64 |
65 | {{site.data.alerts.hr_shaded}}
66 |
67 | {% include footer.html %}
68 |
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | from packaging.version import parse
2 | from configparser import ConfigParser
3 | import setuptools
4 | assert parse(setuptools.__version__)>=parse('36.2')
5 |
6 | # note: all settings are in settings.ini; edit there, not here
7 | config = ConfigParser(delimiters=['='])
8 | config.read('settings.ini')
9 | cfg = config['DEFAULT']
10 |
11 | cfg_keys = 'version description keywords author author_email'.split()
12 | expected = cfg_keys + "lib_name user branch license status min_python audience language".split()
13 | for o in expected: assert o in cfg, "missing expected setting: {}".format(o)
14 | setup_cfg = {o:cfg[o] for o in cfg_keys}
15 |
16 | licenses = {
17 | 'apache2': ('Apache Software License 2.0','OSI Approved :: Apache Software License'),
18 | }
19 | statuses = [ '1 - Planning', '2 - Pre-Alpha', '3 - Alpha',
20 | '4 - Beta', '5 - Production/Stable', '6 - Mature', '7 - Inactive' ]
21 | py_versions = '2.0 2.1 2.2 2.3 2.4 2.5 2.6 2.7 3.0 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8'.split()
22 |
23 | requirements = cfg.get('requirements','').split()
24 | lic = licenses[cfg['license']]
25 | min_python = cfg['min_python']
26 |
27 | setuptools.setup(
28 | name = cfg['lib_name'],
29 | license = lic[0],
30 | classifiers = [
31 | 'Development Status :: ' + statuses[int(cfg['status'])],
32 | 'Intended Audience :: ' + cfg['audience'].title(),
33 | 'License :: ' + lic[1],
34 | 'Natural Language :: ' + cfg['language'].title(),
35 | ] + ['Programming Language :: Python :: '+o for o in py_versions[py_versions.index(min_python):]],
36 | url = 'https://github.com/{}/{}'.format(cfg['user'],cfg['repo_name']),
37 | packages = setuptools.find_packages(),
38 | include_package_data = True,
39 | install_requires = requirements,
40 | python_requires = '>=' + cfg['min_python'],
41 | long_description = open('README.md').read(),
42 | long_description_content_type = 'text/markdown',
43 | zip_safe = False,
44 | entry_points = { 'console_scripts': cfg.get('console_scripts','').split() },
45 | **setup_cfg)
46 |
47 |
--------------------------------------------------------------------------------
/docs/js/customscripts.js:
--------------------------------------------------------------------------------
1 | $('#mysidebar').height($(".nav").height());
2 |
3 |
4 | $( document ).ready(function() {
5 |
6 | //this script says, if the height of the viewport is greater than 800px, then insert affix class, which makes the nav bar float in a fixed
7 | // position as your scroll. if you have a lot of nav items, this height may not work for you.
8 | var h = $(window).height();
9 | //console.log (h);
10 | if (h > 800) {
11 | $( "#mysidebar" ).attr("class", "nav affix");
12 | }
13 | // activate tooltips. although this is a bootstrap js function, it must be activated this way in your theme.
14 | $('[data-toggle="tooltip"]').tooltip({
15 | placement : 'top'
16 | });
17 |
18 | /**
19 | * AnchorJS
20 | */
21 | anchors.add('h2,h3,h4,h5');
22 |
23 | });
24 |
25 | // needed for nav tabs on pages. See Formatting > Nav tabs for more details.
26 | // script from http://stackoverflow.com/questions/10523433/how-do-i-keep-the-current-tab-active-with-twitter-bootstrap-after-a-page-reload
27 | $(function() {
28 | var json, tabsState;
29 | $('a[data-toggle="pill"], a[data-toggle="tab"]').on('shown.bs.tab', function(e) {
30 | var href, json, parentId, tabsState;
31 |
32 | tabsState = localStorage.getItem("tabs-state");
33 | json = JSON.parse(tabsState || "{}");
34 | parentId = $(e.target).parents("ul.nav.nav-pills, ul.nav.nav-tabs").attr("id");
35 | href = $(e.target).attr('href');
36 | json[parentId] = href;
37 |
38 | return localStorage.setItem("tabs-state", JSON.stringify(json));
39 | });
40 |
41 | tabsState = localStorage.getItem("tabs-state");
42 | json = JSON.parse(tabsState || "{}");
43 |
44 | $.each(json, function(containerId, href) {
45 | return $("#" + containerId + " a[href=" + href + "]").tab('show');
46 | });
47 |
48 | $("ul.nav.nav-pills, ul.nav.nav-tabs").each(function() {
49 | var $this = $(this);
50 | if (!json[$this.attr("id")]) {
51 | return $this.find("a[data-toggle=tab]:first, a[data-toggle=pill]:first").tab("show");
52 | }
53 | });
54 | });
55 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # How to contribute
2 |
3 | ## How to get started
4 |
5 | Before anything else, please install the git hooks that run automatic scripts during each commit and merge to strip the notebooks of superfluous metadata (and avoid merge conflicts). After cloning the repository, run the following command inside it:
6 | ```
7 | nbdev_install_git_hooks
8 | ```
9 |
10 | ## Did you find a bug?
11 |
12 | * Ensure the bug was not already reported by searching on GitHub under Issues.
13 | * If you're unable to find an open issue addressing the problem, open a new one. Be sure to include a title and clear description, as much relevant information as possible, and a code sample or an executable test case demonstrating the expected behavior that is not occurring.
14 | * Be sure to add the complete error messages.
15 |
16 | #### Did you write a patch that fixes a bug?
17 |
18 | * Open a new GitHub pull request with the patch.
19 | * Ensure that your PR includes a test that fails without your patch, and pass with it.
20 | * Ensure the PR description clearly describes the problem and solution. Include the relevant issue number if applicable.
21 |
22 | ## PR submission guidelines
23 |
24 | * Keep each PR focused. While it's more convenient, do not combine several unrelated fixes together. Create as many branches as needing to keep each PR focused.
25 | * Do not mix style changes/fixes with "functional" changes. It's very difficult to review such PRs and it most likely get rejected.
26 | * Do not add/remove vertical whitespace. Preserve the original style of the file you edit as much as you can.
27 | * Do not turn an already submitted PR into your development playground. If after you submitted PR, you discovered that more work is needed - close the PR, do the required work and then submit a new PR. Otherwise each of your commits requires attention from maintainers of the project.
28 | * If, however, you submitted a PR and received a request for changes, you should proceed with commits inside that PR, so that the maintainer can see the incremental fixes and won't need to review the whole PR again. In the exception case where you realize it'll take many many commits to complete the requests, then it's probably best to close the PR, do the work and then submit it again. Use common sense where you'd choose one way over another.
29 |
30 | ## Do you want to contribute to the documentation?
31 |
32 | * Docs are automatically created from the notebooks in the nbs folder.
33 |
34 |
--------------------------------------------------------------------------------
/docs/warp_loss.html:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | title: Losses
4 |
5 | keywords: fastai
6 | sidebar: home_sidebar
7 |
8 | summary: "Where all the losses are situated"
9 | ---
10 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
num_tries_gt_zero(scores , batch_size , max_trials , max_num , device )
38 |
39 |
scores: [batch_size x N] float scores
40 | returns: [batch_size x 1] the lowest indice per row where scores were first greater than 0. plus 1
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
warp_loss(positive_predictions , negative_predictions , num_labels , device )
60 |
61 |
positive_predictions: [batch_size x 1] floats between -1 to 1
62 | negative_predictions: [batch_size x N] floats between -1 to 1
63 | num_labels: int total number of labels in dataset (not just the subset you're using for the batch)
64 | device: pytorch.device
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
--------------------------------------------------------------------------------
/warp_loss/losses.py:
--------------------------------------------------------------------------------
1 | # AUTOGENERATED! DO NOT EDIT! File to edit: warp_loss.ipynb (unless otherwise specified).
2 |
3 | __all__ = ['num_tries_gt_zero', 'warp_loss']
4 |
5 | # Cell
6 | import torch
7 | def num_tries_gt_zero(scores, batch_size, max_trials, max_num, device):
8 | '''
9 | scores: [batch_size x N] float scores
10 | returns: [batch_size x 1] the lowest indice per row where scores were first greater than 0. plus 1
11 | '''
12 | tmp = scores.gt(0).nonzero().t()
13 | # We offset these values by 1 to look for unset values (zeros) later
14 | values = tmp[1] + 1
15 | # TODO just allocate normal zero-tensor and fill it?
16 | # Sparse tensors can't be moved with .to() or .cuda() if you want to send in cuda variables first
17 | if device.type == 'cuda':
18 | t = torch.cuda.sparse.LongTensor(tmp, values, torch.Size((batch_size, max_trials+1))).to_dense()
19 | else:
20 | t = torch.sparse.LongTensor(tmp, values, torch.Size((batch_size, max_trials+1))).to_dense()
21 | t[(t == 0)] += max_num # set all unused indices to be max possible number so its not picked by min() call
22 |
23 | tries = torch.min(t, dim=1)[0]
24 | return tries
25 |
26 |
27 | def warp_loss(positive_predictions, negative_predictions, num_labels, device):
28 | '''
29 | positive_predictions: [batch_size x 1] floats between -1 to 1
30 | negative_predictions: [batch_size x N] floats between -1 to 1
31 | num_labels: int total number of labels in dataset (not just the subset you're using for the batch)
32 | device: pytorch.device
33 | '''
34 | batch_size, max_trials = negative_predictions.size(0), negative_predictions.size(1)
35 |
36 | offsets, ones, max_num = (torch.arange(0, batch_size, 1).long().to(device) * (max_trials + 1),
37 | torch.ones(batch_size, 1).float().to(device),
38 | batch_size * (max_trials + 1) )
39 |
40 | sample_scores = (1 + negative_predictions - positive_predictions)
41 | # Add column of ones so we know when we used all our attempts, This is used for indexing and computing should_count_loss if no real value is above 0
42 | sample_scores, negative_predictions = (torch.cat([sample_scores, ones], dim=1),
43 | torch.cat([negative_predictions, ones], dim=1))
44 |
45 | tries = num_tries_gt_zero(sample_scores, batch_size, max_trials, max_num, device)
46 | attempts, trial_offset = tries.float(), (tries - 1) + offsets
47 | loss_weights, should_count_loss = ( torch.log(torch.floor((num_labels - 1) / attempts)),
48 | (attempts <= max_trials).float()) #Don't count loss if we used max number of attempts
49 |
50 | losses = loss_weights * ((1 - positive_predictions.view(-1)) + negative_predictions.view(-1)[trial_offset]) * should_count_loss
51 |
52 | return losses.sum()
53 |
--------------------------------------------------------------------------------
/docs/css/theme-green.css:
--------------------------------------------------------------------------------
1 | .summary {
2 | color: #808080;
3 | border-left: 5px solid #E50E51;
4 | font-size:16px;
5 | }
6 |
7 |
8 | h3 {color: #E50E51; }
9 | h4 {color: #808080; }
10 |
11 | .nav-tabs > li.active > a, .nav-tabs > li.active > a:hover, .nav-tabs > li.active > a:focus {
12 | background-color: #248ec2;
13 | color: white;
14 | }
15 |
16 | .nav > li.active > a {
17 | background-color: #72ac4a;
18 | }
19 |
20 | .nav > li > a:hover {
21 | background-color: #72ac4a;
22 | }
23 |
24 | div.navbar-collapse .dropdown-menu > li > a:hover {
25 | background-color: #72ac4a;
26 | }
27 |
28 | .navbar-inverse .navbar-nav>li>a, .navbar-inverse .navbar-brand {
29 | color: white;
30 | }
31 |
32 | .navbar-inverse .navbar-nav>li>a:hover, a.fa.fa-home.fa-lg.navbar-brand:hover {
33 | color: #f0f0f0;
34 | }
35 |
36 | .nav li.thirdlevel > a {
37 | background-color: #FAFAFA !important;
38 | color: #72ac4a;
39 | font-weight: bold;
40 | }
41 |
42 | a[data-toggle="tooltip"] {
43 | color: #649345;
44 | font-style: italic;
45 | cursor: default;
46 | }
47 |
48 | .navbar-inverse {
49 | background-color: #72ac4a;
50 | border-color: #5b893c;
51 | }
52 |
53 | .navbar-inverse .navbar-nav > .open > a, .navbar-inverse .navbar-nav > .open > a:hover, .navbar-inverse .navbar-nav > .open > a:focus {
54 | color: #5b893c;
55 | }
56 |
57 | .navbar-inverse .navbar-nav > .open > a, .navbar-inverse .navbar-nav > .open > a:hover, .navbar-inverse .navbar-nav > .open > a:focus {
58 | background-color: #5b893c;
59 | color: #ffffff;
60 | }
61 |
62 | /* not sure if using this ...*/
63 | .navbar-inverse .navbar-collapse, .navbar-inverse .navbar-form {
64 | border-color: #72ac4a !important;
65 | }
66 |
67 | .btn-primary {
68 | color: #ffffff;
69 | background-color: #5b893c;
70 | border-color: #5b893c;
71 | }
72 |
73 | .btn-primary:hover,
74 | .btn-primary:focus,
75 | .btn-primary:active,
76 | .btn-primary.active,
77 | .open .dropdown-toggle.btn-primary {
78 | background-color: #72ac4a;
79 | border-color: #5b893c;
80 | }
81 |
82 | .printTitle {
83 | color: #5b893c !important;
84 | }
85 |
86 | body.print h1 {color: #5b893c !important; font-size:28px;}
87 | body.print h2 {color: #595959 !important; font-size:24px;}
88 | body.print h3 {color: #E50E51 !important; font-size:14px;}
89 | body.print h4 {color: #679DCE !important; font-size:14px; font-style: italic;}
90 |
91 | .anchorjs-link:hover {
92 | color: #4f7233;
93 | }
94 |
95 | div.sidebarTitle {
96 | color: #E50E51;
97 | }
98 |
99 | li.sidebarTitle {
100 | margin-top:20px;
101 | font-weight:normal;
102 | font-size:130%;
103 | color: #ED1951;
104 | margin-bottom:10px;
105 | margin-left: 5px;
106 | }
107 |
108 | .navbar-inverse .navbar-toggle:focus, .navbar-inverse .navbar-toggle:hover {
109 | background-color: #E50E51;
110 | }
111 |
--------------------------------------------------------------------------------
/docs/_includes/sidebar.html:
--------------------------------------------------------------------------------
1 | {% assign sidebar = site.data.sidebars[page.sidebar].entries %}
2 | {% assign pageurl = page.url | remove: ".html" %}
3 |
4 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/docs/css/theme-blue.css:
--------------------------------------------------------------------------------
1 | .summary {
2 | color: #808080;
3 | border-left: 5px solid #ED1951;
4 | font-size:16px;
5 | }
6 |
7 |
8 | h3 {color: #000000; }
9 | h4 {color: #000000; }
10 |
11 | .nav-tabs > li.active > a, .nav-tabs > li.active > a:hover, .nav-tabs > li.active > a:focus {
12 | background-color: #248ec2;
13 | color: white;
14 | }
15 |
16 | .nav > li.active > a {
17 | background-color: #347DBE;
18 | }
19 |
20 | .nav > li > a:hover {
21 | background-color: #248ec2;
22 | }
23 |
24 | div.navbar-collapse .dropdown-menu > li > a:hover {
25 | background-color: #347DBE;
26 | }
27 |
28 | .nav li.thirdlevel > a {
29 | background-color: #FAFAFA !important;
30 | color: #248EC2;
31 | font-weight: bold;
32 | }
33 |
34 | a[data-toggle="tooltip"] {
35 | color: #649345;
36 | font-style: italic;
37 | cursor: default;
38 | }
39 |
40 | .navbar-inverse {
41 | background-color: #347DBE;
42 | border-color: #015CAE;
43 | }
44 | .navbar-inverse .navbar-nav>li>a, .navbar-inverse .navbar-brand {
45 | color: white;
46 | }
47 |
48 | .navbar-inverse .navbar-nav>li>a:hover, a.fa.fa-home.fa-lg.navbar-brand:hover {
49 | color: #f0f0f0;
50 | }
51 |
52 | a.navbar-brand:hover {
53 | color: #f0f0f0;
54 | }
55 |
56 | .navbar-inverse .navbar-nav > .open > a, .navbar-inverse .navbar-nav > .open > a:hover, .navbar-inverse .navbar-nav > .open > a:focus {
57 | color: #015CAE;
58 | }
59 |
60 | .navbar-inverse .navbar-nav > .open > a, .navbar-inverse .navbar-nav > .open > a:hover, .navbar-inverse .navbar-nav > .open > a:focus {
61 | background-color: #015CAE;
62 | color: #ffffff;
63 | }
64 |
65 | .navbar-inverse .navbar-collapse, .navbar-inverse .navbar-form {
66 | border-color: #248ec2 !important;
67 | }
68 |
69 | .btn-primary {
70 | color: #ffffff;
71 | background-color: #347DBE;
72 | border-color: #347DBE;
73 | }
74 |
75 | .navbar-inverse .navbar-nav > .active > a, .navbar-inverse .navbar-nav > .active > a:hover, .navbar-inverse .navbar-nav > .active > a:focus {
76 | background-color: #347DBE;
77 | }
78 |
79 | .btn-primary:hover,
80 | .btn-primary:focus,
81 | .btn-primary:active,
82 | .btn-primary.active,
83 | .open .dropdown-toggle.btn-primary {
84 | background-color: #248ec2;
85 | border-color: #347DBE;
86 | }
87 |
88 | .printTitle {
89 | color: #015CAE !important;
90 | }
91 |
92 | body.print h1 {color: #015CAE !important; font-size:28px !important;}
93 | body.print h2 {color: #595959 !important; font-size:20px !important;}
94 | body.print h3 {color: #E50E51 !important; font-size:14px !important;}
95 | body.print h4 {color: #679DCE !important; font-size:14px; font-style: italic !important;}
96 |
97 | .anchorjs-link:hover {
98 | color: #216f9b;
99 | }
100 |
101 | div.sidebarTitle {
102 | color: #015CAE;
103 | }
104 |
105 | li.sidebarTitle {
106 | margin-top:20px;
107 | font-weight:normal;
108 | font-size:130%;
109 | color: #ED1951;
110 | margin-bottom:10px;
111 | margin-left: 5px;
112 |
113 | }
114 |
115 | .navbar-inverse .navbar-toggle:focus, .navbar-inverse .navbar-toggle:hover {
116 | background-color: #015CAE;
117 | }
118 |
119 | .navbar-inverse .navbar-toggle {
120 | border-color: #015CAE;
121 | }
122 |
--------------------------------------------------------------------------------
/docs/_includes/topnav.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
13 |
14 |
15 |
16 | Nav
17 |
18 |
19 | {% assign topnav = site.data[page.topnav] %}
20 | {% assign topnav_dropdowns = site.data[page.topnav].topnav_dropdowns %}
21 |
22 | {% for entry in topnav.topnav %}
23 | {% for item in entry.items %}
24 | {% if item.external_url %}
25 | {{item.title}}
26 | {% elsif page.url contains item.url %}
27 | {{item.title}}
28 | {% else %}
29 | {{item.title}}
30 | {% endif %}
31 | {% endfor %}
32 | {% endfor %}
33 |
34 |
35 | {% for entry in topnav_dropdowns %}
36 | {% for folder in entry.folders %}
37 |
38 | {{ folder.title }}
39 |
50 |
51 | {% endfor %}
52 | {% endfor %}
53 | {% if site.google_search %}
54 |
55 | {% include search_google_custom.html %}
56 |
57 | {% endif %}
58 |
59 |
60 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/docs/js/jquery.navgoco.min.js:
--------------------------------------------------------------------------------
1 | /*
2 | * jQuery Navgoco Menus Plugin v0.2.1 (2014-04-11)
3 | * https://github.com/tefra/navgoco
4 | *
5 | * Copyright (c) 2014 Chris T (@tefra)
6 | * BSD - https://github.com/tefra/navgoco/blob/master/LICENSE-BSD
7 | */
8 | !function(a){"use strict";var b=function(b,c,d){return this.el=b,this.$el=a(b),this.options=c,this.uuid=this.$el.attr("id")?this.$el.attr("id"):d,this.state={},this.init(),this};b.prototype={init:function(){var b=this;b._load(),b.$el.find("ul").each(function(c){var d=a(this);d.attr("data-index",c),b.options.save&&b.state.hasOwnProperty(c)?(d.parent().addClass(b.options.openClass),d.show()):d.parent().hasClass(b.options.openClass)?(d.show(),b.state[c]=1):d.hide()});var c=a(" ").prepend(b.options.caretHtml),d=b.$el.find("li > a");b._trigger(c,!1),b._trigger(d,!0),b.$el.find("li:has(ul) > a").prepend(c)},_trigger:function(b,c){var d=this;b.on("click",function(b){b.stopPropagation();var e=c?a(this).next():a(this).parent().next(),f=!1;if(c){var g=a(this).attr("href");f=void 0===g||""===g||"#"===g}if(e=e.length>0?e:!1,d.options.onClickBefore.call(this,b,e),!c||e&&f)b.preventDefault(),d._toggle(e,e.is(":hidden")),d._save();else if(d.options.accordion){var h=d.state=d._parents(a(this));d.$el.find("ul").filter(":visible").each(function(){var b=a(this),c=b.attr("data-index");h.hasOwnProperty(c)||d._toggle(b,!1)}),d._save()}d.options.onClickAfter.call(this,b,e)})},_toggle:function(b,c){var d=this,e=b.attr("data-index"),f=b.parent();if(d.options.onToggleBefore.call(this,b,c),c){if(f.addClass(d.options.openClass),b.slideDown(d.options.slide),d.state[e]=1,d.options.accordion){var g=d.state=d._parents(b);g[e]=d.state[e]=1,d.$el.find("ul").filter(":visible").each(function(){var b=a(this),c=b.attr("data-index");g.hasOwnProperty(c)||d._toggle(b,!1)})}}else f.removeClass(d.options.openClass),b.slideUp(d.options.slide),d.state[e]=0;d.options.onToggleAfter.call(this,b,c)},_parents:function(b,c){var d={},e=b.parent(),f=e.parents("ul");return f.each(function(){var b=a(this),e=b.attr("data-index");return e?void(d[e]=c?b:1):!1}),d},_save:function(){if(this.options.save){var b={};for(var d in this.state)1===this.state[d]&&(b[d]=1);c[this.uuid]=this.state=b,a.cookie(this.options.cookie.name,JSON.stringify(c),this.options.cookie)}},_load:function(){if(this.options.save){if(null===c){var b=a.cookie(this.options.cookie.name);c=b?JSON.parse(b):{}}this.state=c.hasOwnProperty(this.uuid)?c[this.uuid]:{}}},toggle:function(b){var c=this,d=arguments.length;if(1>=d)c.$el.find("ul").each(function(){var d=a(this);c._toggle(d,b)});else{var e,f={},g=Array.prototype.slice.call(arguments,1);d--;for(var h=0;d>h;h++){e=g[h];var i=c.$el.find('ul[data-index="'+e+'"]').first();if(i&&(f[e]=i,b)){var j=c._parents(i,!0);for(var k in j)f.hasOwnProperty(k)||(f[k]=j[k])}}for(e in f)c._toggle(f[e],b)}c._save()},destroy:function(){a.removeData(this.$el),this.$el.find("li:has(ul) > a").unbind("click"),this.$el.find("li:has(ul) > a > span").unbind("click")}},a.fn.navgoco=function(c){if("string"==typeof c&&"_"!==c.charAt(0)&&"init"!==c)var d=!0,e=Array.prototype.slice.call(arguments,1);else c=a.extend({},a.fn.navgoco.defaults,c||{}),a.cookie||(c.save=!1);return this.each(function(f){var g=a(this),h=g.data("navgoco");h||(h=new b(this,d?a.fn.navgoco.defaults:c,f),g.data("navgoco",h)),d&&h[c].apply(h,e)})};var c=null;a.fn.navgoco.defaults={caretHtml:"",accordion:!1,openClass:"open",save:!0,cookie:{name:"navgoco",expires:!1,path:"/"},slide:{duration:400,easing:"swing"},onClickBefore:a.noop,onClickAfter:a.noop,onToggleBefore:a.noop,onToggleAfter:a.noop}}(jQuery);
--------------------------------------------------------------------------------
/docs/_includes/initialize_shuffle.html:
--------------------------------------------------------------------------------
1 |
7 |
8 |
100 |
101 |
102 |
103 |
114 |
115 |
129 |
130 |
131 |
--------------------------------------------------------------------------------
/docs/css/printstyles.css:
--------------------------------------------------------------------------------
1 |
2 | /*body.print .container {max-width: 650px;}*/
3 |
4 | body {
5 | font-size:14px;
6 | }
7 | .nav ul li a {border-top:0px; background-color:transparent; color: #808080; }
8 | #navig a[href] {color: #595959 !important;}
9 | table .table {max-width:650px;}
10 |
11 | #navig li.sectionHead {font-weight: bold; font-size: 18px; color: #595959 !important; }
12 | #navig li {font-weight: normal; }
13 |
14 | #navig a[href]::after { content: leader(".") target-counter(attr(href), page); }
15 |
16 | a[href]::after {
17 | content: " (page " target-counter(attr(href), page) ")"
18 | }
19 |
20 | a[href^="http:"]::after, a[href^="https:"]::after {
21 | content: "";
22 | }
23 |
24 | a[href] {
25 | color: blue !important;
26 | }
27 | a[href*="mailto"]::after, a[data-toggle="tooltip"]::after, a[href].noCrossRef::after {
28 | content: "";
29 | }
30 |
31 |
32 | @page {
33 | margin: 60pt 90pt 60pt 90pt;
34 | font-family: sans-serif;
35 | font-style:none;
36 | color: gray;
37 |
38 | }
39 |
40 | .printTitle {
41 | line-height:30pt;
42 | font-size:27pt;
43 | font-weight: bold;
44 | letter-spacing: -.5px;
45 | margin-bottom:25px;
46 | }
47 |
48 | .printSubtitle {
49 | font-size: 19pt;
50 | color: #cccccc !important;
51 | font-family: "Grotesque MT Light";
52 | line-height: 22pt;
53 | letter-spacing: -.5px;
54 | margin-bottom:20px;
55 | }
56 | .printTitleArea hr {
57 | color: #999999 !important;
58 | height: 2px;
59 | width: 100%;
60 | }
61 |
62 | .printTitleImage {
63 | max-width:300px;
64 | margin-bottom:200px;
65 | }
66 |
67 |
68 | .printTitleImage {
69 | max-width: 250px;
70 | }
71 |
72 | #navig {
73 | /*page-break-before: always;*/
74 | }
75 |
76 | .copyrightBoilerplate {
77 | page-break-before:always;
78 | font-size:14px;
79 | }
80 |
81 | .lastGeneratedDate {
82 | font-style: italic;
83 | font-size:14px;
84 | color: gray;
85 | }
86 |
87 | .alert a {
88 | text-decoration: none !important;
89 | }
90 |
91 |
92 | body.title { page: title }
93 |
94 | @page title {
95 | @top-left {
96 | content: " ";
97 | }
98 | @top-right {
99 | content: " "
100 | }
101 | @bottom-right {
102 | content: " ";
103 | }
104 | @bottom-left {
105 | content: " ";
106 | }
107 | }
108 |
109 | body.frontmatter { page: frontmatter }
110 | body.frontmatter {counter-reset: page 1}
111 |
112 |
113 | @page frontmatter {
114 | @top-left {
115 | content: prince-script(guideName);
116 | }
117 | @top-right {
118 | content: prince-script(datestamp);
119 | }
120 | @bottom-right {
121 | content: counter(page, lower-roman);
122 | }
123 | @bottom-left {
124 | content: "youremail@domain.com"; }
125 | }
126 |
127 | body.first_page {counter-reset: page 1}
128 |
129 | h1 { string-set: doctitle content() }
130 |
131 | @page {
132 | @top-left {
133 | content: string(doctitle);
134 | font-size: 11px;
135 | font-style: italic;
136 | }
137 | @top-right {
138 | content: prince-script(datestamp);
139 | font-size: 11px;
140 | }
141 |
142 | @bottom-right {
143 | content: "Page " counter(page);
144 | font-size: 11px;
145 | }
146 | @bottom-left {
147 | content: prince-script(guideName);
148 | font-size: 11px;
149 | }
150 | }
151 | .alert {
152 | background-color: #fafafa !important;
153 | border-color: #dedede !important;
154 | color: black;
155 | }
156 |
157 | pre {
158 | background-color: #fafafa;
159 | }
160 |
--------------------------------------------------------------------------------
/docs/_includes/head.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | {{ page.title }} | {{ site.site_title }}
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | {% if site.use_math %}
25 |
26 |
27 |
28 |
39 | {% endif %}
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
56 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/docs/css/syntax.css:
--------------------------------------------------------------------------------
1 | .highlight { background: #ffffff; }
2 | .highlight .c { color: #999988; font-style: italic } /* Comment */
3 | .highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
4 | .highlight .k { font-weight: bold } /* Keyword */
5 | .highlight .o { font-weight: bold } /* Operator */
6 | .highlight .cm { color: #999988; font-style: italic } /* Comment.Multiline */
7 | .highlight .cp { color: #999999; font-weight: bold } /* Comment.Preproc */
8 | .highlight .c1 { color: #999988; font-style: italic } /* Comment.Single */
9 | .highlight .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */
10 | .highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
11 | .highlight .gd .x { color: #000000; background-color: #ffaaaa } /* Generic.Deleted.Specific */
12 | .highlight .ge { font-style: italic } /* Generic.Emph */
13 | .highlight .gr { color: #aa0000 } /* Generic.Error */
14 | .highlight .gh { color: #999999 } /* Generic.Heading */
15 | .highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
16 | .highlight .gi .x { color: #000000; background-color: #aaffaa } /* Generic.Inserted.Specific */
17 | .highlight .go { color: #888888 } /* Generic.Output */
18 | .highlight .gp { color: #555555 } /* Generic.Prompt */
19 | .highlight .gs { font-weight: bold } /* Generic.Strong */
20 | .highlight .gu { color: #aaaaaa } /* Generic.Subheading */
21 | .highlight .gt { color: #aa0000 } /* Generic.Traceback */
22 | .highlight .kc { font-weight: bold } /* Keyword.Constant */
23 | .highlight .kd { font-weight: bold } /* Keyword.Declaration */
24 | .highlight .kp { font-weight: bold } /* Keyword.Pseudo */
25 | .highlight .kr { font-weight: bold } /* Keyword.Reserved */
26 | .highlight .kt { color: #445588; font-weight: bold } /* Keyword.Type */
27 | .highlight .m { color: #009999 } /* Literal.Number */
28 | .highlight .s { color: #d14 } /* Literal.String */
29 | .highlight .na { color: #008080 } /* Name.Attribute */
30 | .highlight .nb { color: #0086B3 } /* Name.Builtin */
31 | .highlight .nc { color: #445588; font-weight: bold } /* Name.Class */
32 | .highlight .no { color: #008080 } /* Name.Constant */
33 | .highlight .ni { color: #800080 } /* Name.Entity */
34 | .highlight .ne { color: #990000; font-weight: bold } /* Name.Exception */
35 | .highlight .nf { color: #990000; font-weight: bold } /* Name.Function */
36 | .highlight .nn { color: #555555 } /* Name.Namespace */
37 | .highlight .nt { color: #000080 } /* Name.Tag */
38 | .highlight .nv { color: #008080 } /* Name.Variable */
39 | .highlight .ow { font-weight: bold } /* Operator.Word */
40 | .highlight .w { color: #bbbbbb } /* Text.Whitespace */
41 | .highlight .mf { color: #009999 } /* Literal.Number.Float */
42 | .highlight .mh { color: #009999 } /* Literal.Number.Hex */
43 | .highlight .mi { color: #009999 } /* Literal.Number.Integer */
44 | .highlight .mo { color: #009999 } /* Literal.Number.Oct */
45 | .highlight .sb { color: #d14 } /* Literal.String.Backtick */
46 | .highlight .sc { color: #d14 } /* Literal.String.Char */
47 | .highlight .sd { color: #d14 } /* Literal.String.Doc */
48 | .highlight .s2 { color: #d14 } /* Literal.String.Double */
49 | .highlight .se { color: #d14 } /* Literal.String.Escape */
50 | .highlight .sh { color: #d14 } /* Literal.String.Heredoc */
51 | .highlight .si { color: #d14 } /* Literal.String.Interpol */
52 | .highlight .sx { color: #d14 } /* Literal.String.Other */
53 | .highlight .sr { color: #009926 } /* Literal.String.Regex */
54 | .highlight .s1 { color: #d14 } /* Literal.String.Single */
55 | .highlight .ss { color: #990073 } /* Literal.String.Symbol */
56 | .highlight .bp { color: #999999 } /* Name.Builtin.Pseudo */
57 | .highlight .vc { color: #008080 } /* Name.Variable.Class */
58 | .highlight .vg { color: #008080 } /* Name.Variable.Global */
59 | .highlight .vi { color: #008080 } /* Name.Variable.Instance */
60 | .highlight .il { color: #009999 } /* Literal.Number.Integer.Long */
--------------------------------------------------------------------------------
/docs/js/toc.js:
--------------------------------------------------------------------------------
1 | // https://github.com/ghiculescu/jekyll-table-of-contents
2 | // this library modified by fastai to:
3 | // - update the location.href with the correct anchor when a toc item is clicked on
4 | (function($){
5 | $.fn.toc = function(options) {
6 | var defaults = {
7 | noBackToTopLinks: false,
8 | title: '',
9 | minimumHeaders: 3,
10 | headers: 'h1, h2, h3, h4',
11 | listType: 'ol', // values: [ol|ul]
12 | showEffect: 'show', // values: [show|slideDown|fadeIn|none]
13 | showSpeed: 'slow' // set to 0 to deactivate effect
14 | },
15 | settings = $.extend(defaults, options);
16 |
17 | var headers = $(settings.headers).filter(function() {
18 | // get all headers with an ID
19 | var previousSiblingName = $(this).prev().attr( "name" );
20 | if (!this.id && previousSiblingName) {
21 | this.id = $(this).attr( "id", previousSiblingName.replace(/\./g, "-") );
22 | }
23 | return this.id;
24 | }), output = $(this);
25 | if (!headers.length || headers.length < settings.minimumHeaders || !output.length) {
26 | return;
27 | }
28 |
29 | if (0 === settings.showSpeed) {
30 | settings.showEffect = 'none';
31 | }
32 |
33 | var render = {
34 | show: function() { output.hide().html(html).show(settings.showSpeed); },
35 | slideDown: function() { output.hide().html(html).slideDown(settings.showSpeed); },
36 | fadeIn: function() { output.hide().html(html).fadeIn(settings.showSpeed); },
37 | none: function() { output.html(html); }
38 | };
39 |
40 | var get_level = function(ele) { return parseInt(ele.nodeName.replace("H", ""), 10); }
41 | var highest_level = headers.map(function(_, ele) { return get_level(ele); }).get().sort()[0];
42 | //var return_to_top = ' ';
43 | // other nice icons that can be used instead: glyphicon-upload glyphicon-hand-up glyphicon-chevron-up glyphicon-menu-up glyphicon-triangle-top
44 | var level = get_level(headers[0]),
45 | this_level,
46 | html = settings.title + " <"+settings.listType+">";
47 | headers.on('click', function() {
48 | if (!settings.noBackToTopLinks) {
49 | var pos = $(window).scrollTop();
50 | window.location.hash = this.id;
51 | $(window).scrollTop(pos);
52 | }
53 | })
54 | .addClass('clickable-header')
55 | .each(function(_, header) {
56 | base_url = window.location.href;
57 | base_url = base_url.replace(/#.*$/, "");
58 | this_level = get_level(header);
59 | //if (!settings.noBackToTopLinks && this_level > 1) {
60 | // $(header).addClass('top-level-header').before(return_to_top);
61 | //}
62 | txt = header.textContent.split('¶')[0].split(/\[(test|source)\]/)[0];
63 | if (!txt) {return;}
64 | if (this_level === level) // same level as before; same indenting
65 | html += "" + txt + " ";
66 | else if (this_level <= level){ // higher level than before; end parent ol
67 | for(i = this_level; i < level; i++) {
68 | html += " "+settings.listType+">"
69 | }
70 | html += "" + txt + " ";
71 | }
72 | else if (this_level > level) { // lower level than before; expand the previous to contain a ol
73 | for(i = this_level; i > level; i--) {
74 | html += "<"+settings.listType+">"+((i-level == 2) ? "" : " ")
75 | }
76 | html += "" + txt + " ";
77 | }
78 | level = this_level; // update for the next one
79 | });
80 | html += ""+settings.listType+">";
81 | if (!settings.noBackToTopLinks) {
82 | $(document).on('click', '.back-to-top', function() {
83 | $(window).scrollTop(0);
84 | window.location.hash = '';
85 | });
86 | }
87 |
88 | render[settings.showEffect]();
89 | };
90 | })(jQuery);
91 |
--------------------------------------------------------------------------------
/docs/_layouts/default.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {% include head.html %}
5 |
41 |
46 |
57 | {% if page.datatable == true %}
58 |
59 |
60 |
61 |
66 |
76 | {% endif %}
77 |
78 |
79 |
80 | {% include topnav.html %}
81 |
82 |
83 |
84 |
85 |
86 | {% assign content_col_size = "col-md-12" %}
87 | {% unless page.hide_sidebar %}
88 |
89 |
92 | {% assign content_col_size = "col-md-9" %}
93 | {% endunless %}
94 |
95 |
96 |
97 | {{content}}
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 | {% if site.google_analytics %}
108 | {% include google_analytics.html %}
109 | {% endif %}
110 |
111 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
10 |
11 | # WARP-Pytorch
12 |
13 | > An implementation of WARP loss which uses matrixes and stays on the GPU in PyTorch.
14 |
15 |
16 | This means instead of using a for-loop to find the first offending negative sample that ranks above our positive,
17 | we compute all of them at once. Only later do we find which sample is the first offender, and compute the loss with
18 | respect to this sample.
19 |
20 | The advantage is that it can use the speedups that comes with GPU-usage.
21 |
22 | ## When is WARP loss advantageous?
23 | If you're ranking items or making models for recommendations, it's often advantageous to let your loss function directly
24 | optimize for this case. WARP loss looks at 1 explicit positive up against the implicit negative items that a user never sampled,
25 | and allows us to adjust weights of the network accordingly.
26 |
27 |
28 | ## Install
29 |
30 | `pip install warp_loss`
31 |
32 | ## How to use
33 |
34 | The loss function requires scores for both positive examples, and negative examples to be supplied, such as in the example below.
35 |
36 |
37 |
38 | ```
39 | from torch import nn
40 | import torch
41 |
42 | class OurModel(nn.Module):
43 | def __init__(self, num_labels, emb_dim=10):
44 | super(OurModel, self).__init__()
45 | self.emb = nn.Embedding(num_labels, emb_dim)
46 | self.user_embs = nn.Embedding(1, emb_dim)
47 |
48 | def forward(self, pos, neg):
49 | batch_size = neg.size(0)
50 | one_user_vector = self.user_embs(torch.zeros(1).long())
51 | repeated_user_vector = one_user_vector.repeat((batch_size, 1)).view(batch_size, -1, 1)
52 | pos_res = torch.bmm(self.emb(pos), repeated_user_vector).squeeze(2)
53 | neg_res = torch.bmm(self.emb(neg), repeated_user_vector).squeeze(2)
54 |
55 | return pos_res, neg_res
56 |
57 | num_labels = 100
58 | model = OurModel(num_labels)
59 | ```
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 | ```
68 | pos_labels = torch.randint(high=num_labels, size=(3,1)) # our five labels
69 | neg_labels = torch.randint(high=num_labels, size=(3,2)) # a few random negatives per positive
70 |
71 | pos_res, neg_res = model(pos_labels, neg_labels)
72 | print('Positive Labels:', pos_labels)
73 | print('Negative Labels:', neg_labels)
74 | print('Model positive scores:', pos_res)
75 | print('Model negative scores:', neg_res)
76 | loss = warp_loss(pos_res, neg_res, num_labels=num_labels, device=torch.device('cpu'))
77 | print('Loss:', loss)
78 | loss.backward()
79 | ```
80 |
81 |
82 |
83 |
84 | Positive Labels: tensor([[21],
85 | [71],
86 | [26]])
87 | Negative Labels: tensor([[47, 10],
88 | [56, 78],
89 | [44, 55]])
90 | Model positive scores: tensor([[-4.9562],
91 | [-1.6886],
92 | [ 3.3984]], grad_fn=)
93 | Model negative scores: tensor([[ 1.0491, 4.9357],
94 | [-2.1289, 0.4496],
95 | [ 3.4541, 0.0931]], grad_fn=)
96 | Loss: tensor(39.6134, grad_fn=)
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 | ```
106 | print('We can also see that the gradient is only active for 2x the number of positive labels:', (model.emb.weight.grad.sum(1) != 0).sum().item())
107 | print('Meaning we correctly discard the gradients for all other than the offending negative label.')
108 | ```
109 |
110 |
111 |
112 |
113 | We can also see that the gradient is only active for 2x the number of positive labels: 6
114 | Meaning we correctly discard the gradients for all other than the offending negative label.
115 |
116 |
117 |
118 |
119 |
120 |
121 | ## Assumptions
122 | The loss function assumes you have already sampled your negatives randomly.
123 |
124 | As an example this could be done in your dataloader:
125 |
126 | 1. Assume we have a total dataset of 100 items
127 | 2. Select a positive sample with index 8
128 | 2. Your negatives should be a random selection from 0-100 excluding 8.
129 |
130 | Ex input to loss function: model scores for pos: [8] neg: [88, 3, 99, 7]
131 |
132 | Should work on all pytorch-versions from 0.4 and up
133 |
134 | ### References
135 | * [WSABIE: Scaling Up To Large Vocabulary Image Annotation](https://static.googleusercontent.com/media/research.google.com/en//pubs/archive/37180.pdf)
136 | * [Intro to WARP loss - Automatic differentiation and PyTorch](https://medium.com/@gabrieltseng/intro-to-warp-loss-automatic-differentiation-and-pytorch-b6aa5083187a)
137 | * [LightFM](https://github.com/lyst/lightfm) as a reference implementaiton
138 |
--------------------------------------------------------------------------------
/docs/js/jekyll-search.js:
--------------------------------------------------------------------------------
1 | !function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a="function"==typeof require&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}for(var i="function"==typeof require&&require,o=0;o=0}var self=this;self.matches=function(string,crit){return"string"!=typeof string?!1:(string=string.trim(),doMatch(string,crit))}}module.exports=new LiteralSearchStrategy},{}],4:[function(require,module){module.exports=function(){function findMatches(store,crit,strategy){for(var data=store.get(),i=0;i{title} ',noResultsText:"No results found",limit:10,fuzzy:!1};self.init=function(_opt){validateOptions(_opt),assignOptions(_opt),isJSON(opt.dataSource)?initWithJSON(opt.dataSource):initWithURL(opt.dataSource)}}var Searcher=require("./Searcher"),Templater=require("./Templater"),Store=require("./Store"),JSONLoader=require("./JSONLoader"),searcher=new Searcher,templater=new Templater,store=new Store,jsonLoader=new JSONLoader;window.SimpleJekyllSearch=new SimpleJekyllSearch}(window,document)},{"./JSONLoader":1,"./Searcher":4,"./Store":5,"./Templater":6}]},{},[7]);
2 |
--------------------------------------------------------------------------------
/warp_loss.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "code",
5 | "execution_count": null,
6 | "metadata": {},
7 | "outputs": [],
8 | "source": [
9 | "# default_exp losses"
10 | ]
11 | },
12 | {
13 | "cell_type": "markdown",
14 | "metadata": {},
15 | "source": [
16 | "# Losses\n",
17 | "\n",
18 | "> Where all the losses are situated"
19 | ]
20 | },
21 | {
22 | "cell_type": "code",
23 | "execution_count": null,
24 | "metadata": {},
25 | "outputs": [],
26 | "source": [
27 | "#hide\n",
28 | "from nbdev.showdoc import *"
29 | ]
30 | },
31 | {
32 | "cell_type": "code",
33 | "execution_count": null,
34 | "metadata": {},
35 | "outputs": [],
36 | "source": [
37 | "#export\n",
38 | "import torch\n",
39 | "def num_tries_gt_zero(scores, batch_size, max_trials, max_num, device):\n",
40 | " '''\n",
41 | " scores: [batch_size x N] float scores\n",
42 | " returns: [batch_size x 1] the lowest indice per row where scores were first greater than 0. plus 1\n",
43 | " '''\n",
44 | " tmp = scores.gt(0).nonzero().t()\n",
45 | " # We offset these values by 1 to look for unset values (zeros) later\n",
46 | " values = tmp[1] + 1\n",
47 | " # TODO just allocate normal zero-tensor and fill it?\n",
48 | " # Sparse tensors can't be moved with .to() or .cuda() if you want to send in cuda variables first\n",
49 | " if device.type == 'cuda':\n",
50 | " t = torch.cuda.sparse.LongTensor(tmp, values, torch.Size((batch_size, max_trials+1))).to_dense()\n",
51 | " else:\n",
52 | " t = torch.sparse.LongTensor(tmp, values, torch.Size((batch_size, max_trials+1))).to_dense()\n",
53 | " t[(t == 0)] += max_num # set all unused indices to be max possible number so its not picked by min() call\n",
54 | "\n",
55 | " tries = torch.min(t, dim=1)[0]\n",
56 | " return tries\n",
57 | "\n",
58 | "\n",
59 | "def warp_loss(positive_predictions, negative_predictions, num_labels, device):\n",
60 | " '''\n",
61 | " positive_predictions: [batch_size x 1] floats between -1 to 1\n",
62 | " negative_predictions: [batch_size x N] floats between -1 to 1\n",
63 | " num_labels: int total number of labels in dataset (not just the subset you're using for the batch)\n",
64 | " device: pytorch.device\n",
65 | " '''\n",
66 | " batch_size, max_trials = negative_predictions.size(0), negative_predictions.size(1)\n",
67 | "\n",
68 | " offsets, ones, max_num = (torch.arange(0, batch_size, 1).long().to(device) * (max_trials + 1),\n",
69 | " torch.ones(batch_size, 1).float().to(device),\n",
70 | " batch_size * (max_trials + 1) )\n",
71 | "\n",
72 | " sample_scores = (1 + negative_predictions - positive_predictions)\n",
73 | " # Add column of ones so we know when we used all our attempts, This is used for indexing and computing should_count_loss if no real value is above 0\n",
74 | " sample_scores, negative_predictions = (torch.cat([sample_scores, ones], dim=1),\n",
75 | " torch.cat([negative_predictions, ones], dim=1))\n",
76 | "\n",
77 | " tries = num_tries_gt_zero(sample_scores, batch_size, max_trials, max_num, device)\n",
78 | " attempts, trial_offset = tries.float(), (tries - 1) + offsets\n",
79 | " loss_weights, should_count_loss = ( torch.log(torch.floor((num_labels - 1) / attempts)),\n",
80 | " (attempts <= max_trials).float()) #Don't count loss if we used max number of attempts\n",
81 | "\n",
82 | " losses = loss_weights * ((1 - positive_predictions.view(-1)) + negative_predictions.view(-1)[trial_offset]) * should_count_loss\n",
83 | "\n",
84 | " return losses.sum()\n"
85 | ]
86 | },
87 | {
88 | "cell_type": "code",
89 | "execution_count": null,
90 | "metadata": {},
91 | "outputs": [],
92 | "source": [
93 | "#hide\n",
94 | "import numpy as np\n",
95 | "\n",
96 | "\n",
97 | "cpu_device = torch.device('cpu')\n",
98 | "max_value = num_labels = 10\n",
99 | "\n",
100 | "## warp-loss tests\n",
101 | "def ground_truth(pos_val, neg_val, num_attempts=1, num_labels=10):\n",
102 | " num_labels -= 1\n",
103 | " loss_weight = np.log(np.floor(num_labels / float(num_attempts)))\n",
104 | "\n",
105 | " return loss_weight * ((1-pos_val) + neg_val)\n",
106 | "\n",
107 | "comp_pos = torch.FloatTensor([[0.1], [0.9], [1]])\n",
108 | "comp_neg = torch.FloatTensor([[-1, 0.3, 0.5], [-1, -1, 0.3], [0.3, 0.5, -1]])\n",
109 | "comp_scores = (1 + comp_neg) - comp_pos\n",
110 | "\n",
111 | "def test_num_tries():\n",
112 | " simple = torch.FloatTensor([[0.5, -0.5], [-0.5, 0.5]])\n",
113 | " res = num_tries_gt_zero(simple, 2, 2, max_value, cpu_device)\n",
114 | " ans = torch.LongTensor([1, 2])\n",
115 | " for i, v in enumerate(res.long()):\n",
116 | " assert v == ans[i]\n",
117 | "\n",
118 | " res = num_tries_gt_zero(comp_scores, 3, 3, max_value, cpu_device)\n",
119 | " ans = torch.LongTensor([2, 3, 1])\n",
120 | " for i, v in enumerate(res.long()):\n",
121 | " assert v == ans[i]\n",
122 | "\n",
123 | "\n",
124 | "def test_ground_truth():\n",
125 | " # these variables should always trigger on first index\n",
126 | " pos = torch.rand(2, 1).to(cpu_device)\n",
127 | " neg = torch.rand(2, 3).to(cpu_device)\n",
128 | " res = warp_loss(pos.view(-1, 1), neg, num_labels, cpu_device)\n",
129 | "\n",
130 | " assert res == ground_truth(pos[0], neg[0][0], num_labels=num_labels) + ground_truth(pos[1], neg[1][0], num_labels=num_labels)\n",
131 | "\n",
132 | " res = warp_loss(comp_pos.view(-1, 1), comp_neg, num_labels, cpu_device)\n",
133 | "\n",
134 | " gt = np.sum(np.array([ground_truth(comp_pos[i], comp_neg[i][idx-1], num_attempts=idx, num_labels=num_labels)\n",
135 | " for i, idx in enumerate(num_tries_gt_zero(comp_scores, 3, 3, max_value, cpu_device))]))\n",
136 | "\n",
137 | " assert np.allclose(res.data.numpy(), gt)\n",
138 | "\n",
139 | "def test_no_offending_scores():\n",
140 | " pos = torch.FloatTensor([1, 1])\n",
141 | " neg = torch.FloatTensor([[-1, -1, -1],[-1, -1, -1]])\n",
142 | " res = warp_loss(pos.view(-1, 1), neg, num_labels, cpu_device)\n",
143 | " \n",
144 | " assert res == 0\n",
145 | "\n",
146 | "test_num_tries()\n",
147 | "test_ground_truth()\n",
148 | "test_no_offending_scores()"
149 | ]
150 | },
151 | {
152 | "cell_type": "code",
153 | "execution_count": null,
154 | "metadata": {},
155 | "outputs": [],
156 | "source": []
157 | }
158 | ],
159 | "metadata": {
160 | "kernelspec": {
161 | "display_name": "Python 3",
162 | "language": "python",
163 | "name": "python3"
164 | }
165 | },
166 | "nbformat": 4,
167 | "nbformat_minor": 2
168 | }
169 |
--------------------------------------------------------------------------------
/index.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "code",
5 | "execution_count": null,
6 | "metadata": {},
7 | "outputs": [],
8 | "source": [
9 | "#hide\n",
10 | "from warp_loss.losses import warp_loss"
11 | ]
12 | },
13 | {
14 | "cell_type": "markdown",
15 | "metadata": {},
16 | "source": [
17 | "# WARP-Pytorch\n",
18 | "\n",
19 | "> An implementation of WARP loss which uses matrixes and stays on the GPU in PyTorch."
20 | ]
21 | },
22 | {
23 | "cell_type": "markdown",
24 | "metadata": {},
25 | "source": [
26 | "This means instead of using a for-loop to find the first offending negative sample that ranks above our positive,\n",
27 | "we compute all of them at once. Only later do we find which sample is the first offender, and compute the loss with\n",
28 | "respect to this sample.\n",
29 | "\n",
30 | "The advantage is that it can use the speedups that comes with GPU-usage. \n",
31 | "\n",
32 | "## When is WARP loss advantageous?\n",
33 | "If you're ranking items or making models for recommendations, it's often advantageous to let your loss function directly\n",
34 | "optimize for this case. WARP loss looks at 1 explicit positive up against the implicit negative items that a user never sampled,\n",
35 | "and allows us to adjust weights of the network accordingly.\n"
36 | ]
37 | },
38 | {
39 | "cell_type": "markdown",
40 | "metadata": {},
41 | "source": [
42 | "## Install"
43 | ]
44 | },
45 | {
46 | "cell_type": "markdown",
47 | "metadata": {},
48 | "source": [
49 | "`pip install warp_loss`"
50 | ]
51 | },
52 | {
53 | "cell_type": "markdown",
54 | "metadata": {},
55 | "source": [
56 | "## How to use"
57 | ]
58 | },
59 | {
60 | "cell_type": "markdown",
61 | "metadata": {},
62 | "source": [
63 | "The loss function requires scores for both positive examples, and negative examples to be supplied, such as in the example below."
64 | ]
65 | },
66 | {
67 | "cell_type": "code",
68 | "execution_count": null,
69 | "metadata": {},
70 | "outputs": [],
71 | "source": [
72 | "from torch import nn\n",
73 | "import torch\n",
74 | "\n",
75 | "class OurModel(nn.Module):\n",
76 | " def __init__(self, num_labels, emb_dim=10):\n",
77 | " super(OurModel, self).__init__()\n",
78 | " self.emb = nn.Embedding(num_labels, emb_dim)\n",
79 | " self.user_embs = nn.Embedding(1, emb_dim)\n",
80 | "\n",
81 | " def forward(self, pos, neg):\n",
82 | " batch_size = neg.size(0)\n",
83 | " one_user_vector = self.user_embs(torch.zeros(1).long())\n",
84 | " repeated_user_vector = one_user_vector.repeat((batch_size, 1)).view(batch_size, -1, 1)\n",
85 | " pos_res = torch.bmm(self.emb(pos), repeated_user_vector).squeeze(2)\n",
86 | " neg_res = torch.bmm(self.emb(neg), repeated_user_vector).squeeze(2)\n",
87 | "\n",
88 | " return pos_res, neg_res\n",
89 | " \n",
90 | "num_labels = 100\n",
91 | "model = OurModel(num_labels)"
92 | ]
93 | },
94 | {
95 | "cell_type": "code",
96 | "execution_count": null,
97 | "metadata": {},
98 | "outputs": [
99 | {
100 | "name": "stdout",
101 | "output_type": "stream",
102 | "text": "Positive Labels: tensor([[21],\n [71],\n [26]])\nNegative Labels: tensor([[47, 10],\n [56, 78],\n [44, 55]])\nModel positive scores: tensor([[-4.9562],\n [-1.6886],\n [ 3.3984]], grad_fn=)\nModel negative scores: tensor([[ 1.0491, 4.9357],\n [-2.1289, 0.4496],\n [ 3.4541, 0.0931]], grad_fn=)\nLoss: tensor(39.6134, grad_fn=)\n"
103 | }
104 | ],
105 | "source": [
106 | "pos_labels = torch.randint(high=num_labels, size=(3,1)) # our five labels\n",
107 | "neg_labels = torch.randint(high=num_labels, size=(3,2)) # a few random negatives per positive\n",
108 | "\n",
109 | "pos_res, neg_res = model(pos_labels, neg_labels)\n",
110 | "print('Positive Labels:', pos_labels)\n",
111 | "print('Negative Labels:', neg_labels)\n",
112 | "print('Model positive scores:', pos_res)\n",
113 | "print('Model negative scores:', neg_res)\n",
114 | "loss = warp_loss(pos_res, neg_res, num_labels=num_labels, device=torch.device('cpu'))\n",
115 | "print('Loss:', loss)\n",
116 | "loss.backward()"
117 | ]
118 | },
119 | {
120 | "cell_type": "code",
121 | "execution_count": null,
122 | "metadata": {},
123 | "outputs": [
124 | {
125 | "name": "stdout",
126 | "output_type": "stream",
127 | "text": "We can also see that the gradient is only active for 2x the number of positive labels: 6\nMeaning we correctly discard the gradients for all other than the offending negative label.\n"
128 | }
129 | ],
130 | "source": [
131 | "print('We can also see that the gradient is only active for 2x the number of positive labels:', (model.emb.weight.grad.sum(1) != 0).sum().item())\n",
132 | "print('Meaning we correctly discard the gradients for all other than the offending negative label.')"
133 | ]
134 | },
135 | {
136 | "cell_type": "markdown",
137 | "execution_count": null,
138 | "metadata": {},
139 | "outputs": [
140 | {
141 | "ename": "SyntaxError",
142 | "evalue": "invalid syntax (, line 2)",
143 | "output_type": "error",
144 | "traceback": [
145 | "\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m2\u001b[0m\n\u001b[0;31m The loss function assumes you have already sampled your negatives randomly.\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n"
146 | ]
147 | }
148 | ],
149 | "source": [
150 | "## Assumptions\n",
151 | "The loss function assumes you have already sampled your negatives randomly.\n",
152 | "\n",
153 | "As an example this could be done in your dataloader:\n",
154 | "\n",
155 | "1. Assume we have a total dataset of 100 items\n",
156 | "2. Select a positive sample with index 8\n",
157 | "2. Your negatives should be a random selection from 0-100 excluding 8.\n",
158 | "\n",
159 | "Ex input to loss function: model scores for pos: [8] neg: [88, 3, 99, 7]\n",
160 | "\n",
161 | "Should work on all pytorch-versions from 0.4 and up\n",
162 | "\n",
163 | "### References\n",
164 | "* [WSABIE: Scaling Up To Large Vocabulary Image Annotation](https://static.googleusercontent.com/media/research.google.com/en//pubs/archive/37180.pdf)\n",
165 | "* [Intro to WARP loss - Automatic differentiation and PyTorch](https://medium.com/@gabrieltseng/intro-to-warp-loss-automatic-differentiation-and-pytorch-b6aa5083187a)\n",
166 | "* [LightFM](https://github.com/lyst/lightfm) as a reference implementaiton"
167 | ]
168 | },
169 | {
170 | "cell_type": "code",
171 | "execution_count": null,
172 | "metadata": {},
173 | "outputs": [],
174 | "source": []
175 | }
176 | ],
177 | "metadata": {
178 | "kernelspec": {
179 | "display_name": "Python 3",
180 | "language": "python",
181 | "name": "python3"
182 | }
183 | },
184 | "nbformat": 4,
185 | "nbformat_minor": 2
186 | }
187 |
--------------------------------------------------------------------------------
/docs/Gemfile.lock:
--------------------------------------------------------------------------------
1 | GEM
2 | remote: https://rubygems.org/
3 | specs:
4 | activesupport (4.2.11.1)
5 | i18n (~> 0.7)
6 | minitest (~> 5.1)
7 | thread_safe (~> 0.3, >= 0.3.4)
8 | tzinfo (~> 1.1)
9 | addressable (2.7.0)
10 | public_suffix (>= 2.0.2, < 5.0)
11 | coffee-script (2.4.1)
12 | coffee-script-source
13 | execjs
14 | coffee-script-source (1.11.1)
15 | colorator (1.1.0)
16 | commonmarker (0.17.13)
17 | ruby-enum (~> 0.5)
18 | concurrent-ruby (1.1.5)
19 | dnsruby (1.61.3)
20 | addressable (~> 2.5)
21 | em-websocket (0.5.1)
22 | eventmachine (>= 0.12.9)
23 | http_parser.rb (~> 0.6.0)
24 | ethon (0.12.0)
25 | ffi (>= 1.3.0)
26 | eventmachine (1.2.7)
27 | execjs (2.7.0)
28 | faraday (0.17.0)
29 | multipart-post (>= 1.2, < 3)
30 | ffi (1.11.3)
31 | forwardable-extended (2.6.0)
32 | gemoji (3.0.1)
33 | github-pages (202)
34 | activesupport (= 4.2.11.1)
35 | github-pages-health-check (= 1.16.1)
36 | jekyll (= 3.8.5)
37 | jekyll-avatar (= 0.6.0)
38 | jekyll-coffeescript (= 1.1.1)
39 | jekyll-commonmark-ghpages (= 0.1.6)
40 | jekyll-default-layout (= 0.1.4)
41 | jekyll-feed (= 0.11.0)
42 | jekyll-gist (= 1.5.0)
43 | jekyll-github-metadata (= 2.12.1)
44 | jekyll-mentions (= 1.4.1)
45 | jekyll-optional-front-matter (= 0.3.0)
46 | jekyll-paginate (= 1.1.0)
47 | jekyll-readme-index (= 0.2.0)
48 | jekyll-redirect-from (= 0.14.0)
49 | jekyll-relative-links (= 0.6.0)
50 | jekyll-remote-theme (= 0.4.0)
51 | jekyll-sass-converter (= 1.5.2)
52 | jekyll-seo-tag (= 2.5.0)
53 | jekyll-sitemap (= 1.2.0)
54 | jekyll-swiss (= 0.4.0)
55 | jekyll-theme-architect (= 0.1.1)
56 | jekyll-theme-cayman (= 0.1.1)
57 | jekyll-theme-dinky (= 0.1.1)
58 | jekyll-theme-hacker (= 0.1.1)
59 | jekyll-theme-leap-day (= 0.1.1)
60 | jekyll-theme-merlot (= 0.1.1)
61 | jekyll-theme-midnight (= 0.1.1)
62 | jekyll-theme-minimal (= 0.1.1)
63 | jekyll-theme-modernist (= 0.1.1)
64 | jekyll-theme-primer (= 0.5.3)
65 | jekyll-theme-slate (= 0.1.1)
66 | jekyll-theme-tactile (= 0.1.1)
67 | jekyll-theme-time-machine (= 0.1.1)
68 | jekyll-titles-from-headings (= 0.5.1)
69 | jemoji (= 0.10.2)
70 | kramdown (= 1.17.0)
71 | liquid (= 4.0.0)
72 | listen (= 3.1.5)
73 | mercenary (~> 0.3)
74 | minima (= 2.5.0)
75 | nokogiri (>= 1.10.4, < 2.0)
76 | rouge (= 3.11.0)
77 | terminal-table (~> 1.4)
78 | github-pages-health-check (1.16.1)
79 | addressable (~> 2.3)
80 | dnsruby (~> 1.60)
81 | octokit (~> 4.0)
82 | public_suffix (~> 3.0)
83 | typhoeus (~> 1.3)
84 | html-pipeline (2.12.2)
85 | activesupport (>= 2)
86 | nokogiri (>= 1.4)
87 | http_parser.rb (0.6.0)
88 | i18n (0.9.5)
89 | concurrent-ruby (~> 1.0)
90 | jekyll (3.8.5)
91 | addressable (~> 2.4)
92 | colorator (~> 1.0)
93 | em-websocket (~> 0.5)
94 | i18n (~> 0.7)
95 | jekyll-sass-converter (~> 1.0)
96 | jekyll-watch (~> 2.0)
97 | kramdown (~> 1.14)
98 | liquid (~> 4.0)
99 | mercenary (~> 0.3.3)
100 | pathutil (~> 0.9)
101 | rouge (>= 1.7, < 4)
102 | safe_yaml (~> 1.0)
103 | jekyll-avatar (0.6.0)
104 | jekyll (~> 3.0)
105 | jekyll-coffeescript (1.1.1)
106 | coffee-script (~> 2.2)
107 | coffee-script-source (~> 1.11.1)
108 | jekyll-commonmark (1.3.1)
109 | commonmarker (~> 0.14)
110 | jekyll (>= 3.7, < 5.0)
111 | jekyll-commonmark-ghpages (0.1.6)
112 | commonmarker (~> 0.17.6)
113 | jekyll-commonmark (~> 1.2)
114 | rouge (>= 2.0, < 4.0)
115 | jekyll-default-layout (0.1.4)
116 | jekyll (~> 3.0)
117 | jekyll-feed (0.11.0)
118 | jekyll (~> 3.3)
119 | jekyll-gist (1.5.0)
120 | octokit (~> 4.2)
121 | jekyll-github-metadata (2.12.1)
122 | jekyll (~> 3.4)
123 | octokit (~> 4.0, != 4.4.0)
124 | jekyll-mentions (1.4.1)
125 | html-pipeline (~> 2.3)
126 | jekyll (~> 3.0)
127 | jekyll-optional-front-matter (0.3.0)
128 | jekyll (~> 3.0)
129 | jekyll-paginate (1.1.0)
130 | jekyll-readme-index (0.2.0)
131 | jekyll (~> 3.0)
132 | jekyll-redirect-from (0.14.0)
133 | jekyll (~> 3.3)
134 | jekyll-relative-links (0.6.0)
135 | jekyll (~> 3.3)
136 | jekyll-remote-theme (0.4.0)
137 | addressable (~> 2.0)
138 | jekyll (~> 3.5)
139 | rubyzip (>= 1.2.1, < 3.0)
140 | jekyll-sass-converter (1.5.2)
141 | sass (~> 3.4)
142 | jekyll-seo-tag (2.5.0)
143 | jekyll (~> 3.3)
144 | jekyll-sitemap (1.2.0)
145 | jekyll (~> 3.3)
146 | jekyll-swiss (0.4.0)
147 | jekyll-theme-architect (0.1.1)
148 | jekyll (~> 3.5)
149 | jekyll-seo-tag (~> 2.0)
150 | jekyll-theme-cayman (0.1.1)
151 | jekyll (~> 3.5)
152 | jekyll-seo-tag (~> 2.0)
153 | jekyll-theme-dinky (0.1.1)
154 | jekyll (~> 3.5)
155 | jekyll-seo-tag (~> 2.0)
156 | jekyll-theme-hacker (0.1.1)
157 | jekyll (~> 3.5)
158 | jekyll-seo-tag (~> 2.0)
159 | jekyll-theme-leap-day (0.1.1)
160 | jekyll (~> 3.5)
161 | jekyll-seo-tag (~> 2.0)
162 | jekyll-theme-merlot (0.1.1)
163 | jekyll (~> 3.5)
164 | jekyll-seo-tag (~> 2.0)
165 | jekyll-theme-midnight (0.1.1)
166 | jekyll (~> 3.5)
167 | jekyll-seo-tag (~> 2.0)
168 | jekyll-theme-minimal (0.1.1)
169 | jekyll (~> 3.5)
170 | jekyll-seo-tag (~> 2.0)
171 | jekyll-theme-modernist (0.1.1)
172 | jekyll (~> 3.5)
173 | jekyll-seo-tag (~> 2.0)
174 | jekyll-theme-primer (0.5.3)
175 | jekyll (~> 3.5)
176 | jekyll-github-metadata (~> 2.9)
177 | jekyll-seo-tag (~> 2.0)
178 | jekyll-theme-slate (0.1.1)
179 | jekyll (~> 3.5)
180 | jekyll-seo-tag (~> 2.0)
181 | jekyll-theme-tactile (0.1.1)
182 | jekyll (~> 3.5)
183 | jekyll-seo-tag (~> 2.0)
184 | jekyll-theme-time-machine (0.1.1)
185 | jekyll (~> 3.5)
186 | jekyll-seo-tag (~> 2.0)
187 | jekyll-titles-from-headings (0.5.1)
188 | jekyll (~> 3.3)
189 | jekyll-watch (2.2.1)
190 | listen (~> 3.0)
191 | jemoji (0.10.2)
192 | gemoji (~> 3.0)
193 | html-pipeline (~> 2.2)
194 | jekyll (~> 3.0)
195 | kramdown (1.17.0)
196 | liquid (4.0.0)
197 | listen (3.1.5)
198 | rb-fsevent (~> 0.9, >= 0.9.4)
199 | rb-inotify (~> 0.9, >= 0.9.7)
200 | ruby_dep (~> 1.2)
201 | mercenary (0.3.6)
202 | mini_portile2 (2.4.0)
203 | minima (2.5.0)
204 | jekyll (~> 3.5)
205 | jekyll-feed (~> 0.9)
206 | jekyll-seo-tag (~> 2.1)
207 | minitest (5.13.0)
208 | multipart-post (2.1.1)
209 | nokogiri (1.10.8)
210 | mini_portile2 (~> 2.4.0)
211 | octokit (4.14.0)
212 | sawyer (~> 0.8.0, >= 0.5.3)
213 | pathutil (0.16.2)
214 | forwardable-extended (~> 2.6)
215 | public_suffix (3.1.1)
216 | rb-fsevent (0.10.3)
217 | rb-inotify (0.10.0)
218 | ffi (~> 1.0)
219 | rouge (3.11.0)
220 | ruby-enum (0.7.2)
221 | i18n
222 | ruby_dep (1.5.0)
223 | rubyzip (2.0.0)
224 | safe_yaml (1.0.5)
225 | sass (3.7.4)
226 | sass-listen (~> 4.0.0)
227 | sass-listen (4.0.0)
228 | rb-fsevent (~> 0.9, >= 0.9.4)
229 | rb-inotify (~> 0.9, >= 0.9.7)
230 | sawyer (0.8.2)
231 | addressable (>= 2.3.5)
232 | faraday (> 0.8, < 2.0)
233 | terminal-table (1.8.0)
234 | unicode-display_width (~> 1.1, >= 1.1.1)
235 | thread_safe (0.3.6)
236 | typhoeus (1.3.1)
237 | ethon (>= 0.9.0)
238 | tzinfo (1.2.5)
239 | thread_safe (~> 0.1)
240 | unicode-display_width (1.6.0)
241 |
242 | PLATFORMS
243 | ruby
244 |
245 | DEPENDENCIES
246 | github-pages
247 | jekyll (~> 3.7)
248 |
249 | BUNDLED WITH
250 | 2.0.2
251 |
--------------------------------------------------------------------------------
/docs/index.html:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | title: WARP-Pytorch
4 |
5 | keywords: fastai
6 | sidebar: home_sidebar
7 |
8 | summary: "An implementation of WARP loss which uses matrixes and stays on the GPU in PyTorch."
9 | ---
10 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
This means instead of using a for-loop to find the first offending negative sample that ranks above our positive,
28 | we compute all of them at once. Only later do we find which sample is the first offender, and compute the loss with
29 | respect to this sample.
30 |
The advantage is that it can use the speedups that comes with GPU-usage.
31 |
When is WARP loss advantageous?¶ If you're ranking items or making models for recommendations, it's often advantageous to let your loss function directly
32 | optimize for this case. WARP loss looks at 1 explicit positive up against the implicit negative items that a user never sampled,
33 | and allows us to adjust weights of the network accordingly.
34 |
35 |
36 |
37 |
38 |
44 |
45 |
46 |
pip install warp_loss
47 |
48 |
49 |
50 |
51 |
57 |
58 |
59 |
The loss function requires scores for both positive examples, and negative examples to be supplied, such as in the example below.
60 |
61 |
62 |
63 |
64 |
96 |
97 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
Positive Labels: tensor([[21],
125 | [71],
126 | [26]])
127 | Negative Labels: tensor([[47, 10],
128 | [56, 78],
129 | [44, 55]])
130 | Model positive scores: tensor([[-4.9562],
131 | [-1.6886],
132 | [ 3.3984]], grad_fn=<SqueezeBackward1>)
133 | Model negative scores: tensor([[ 1.0491, 4.9357],
134 | [-2.1289, 0.4496],
135 | [ 3.4541, 0.0931]], grad_fn=<SqueezeBackward1>)
136 | Loss: tensor(39.6134, grad_fn=<SumBackward0>)
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
We can also see that the gradient is only active for 2x the number of positive labels: 6
165 | Meaning we correctly discard the gradients for all other than the offending negative label.
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
Assumptions¶ The loss function assumes you have already sampled your negatives randomly.
177 |
As an example this could be done in your dataloader:
178 |
179 | Assume we have a total dataset of 100 items
180 | Select a positive sample with index 8
181 | Your negatives should be a random selection from 0-100 excluding 8.
182 |
183 |
Ex input to loss function: model scores for pos: [8] neg: [88, 3, 99, 7]
184 |
Should work on all pytorch-versions from 0.4 and up
185 |
References¶
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
--------------------------------------------------------------------------------
/docs/css/font-awesome.min.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome
3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
4 | */@font-face{font-family:'FontAwesome';src:url('fonts/fontawesome-webfont.eot?v=4.7.0');src:url('fonts/fontawesome-webfont.eot?#iefix&v=4.7.0') format('embedded-opentype'),url('fonts/fontawesome-webfont.woff2?v=4.7.0') format('woff2'),url('fonts/fontawesome-webfont.woff?v=4.7.0') format('woff'),url('fonts/fontawesome-webfont.ttf?v=4.7.0') format('truetype'),url('fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-feed:before,.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-resistance:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-intersex:before,.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-genderless:before{content:"\f22d"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-hotel:before,.fa-bed:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}.fa-yc:before,.fa-y-combinator:before{content:"\f23b"}.fa-optin-monster:before{content:"\f23c"}.fa-opencart:before{content:"\f23d"}.fa-expeditedssl:before{content:"\f23e"}.fa-battery-4:before,.fa-battery:before,.fa-battery-full:before{content:"\f240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-battery-2:before,.fa-battery-half:before{content:"\f242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\f243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-mouse-pointer:before{content:"\f245"}.fa-i-cursor:before{content:"\f246"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-sticky-note:before{content:"\f249"}.fa-sticky-note-o:before{content:"\f24a"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-diners-club:before{content:"\f24c"}.fa-clone:before{content:"\f24d"}.fa-balance-scale:before{content:"\f24e"}.fa-hourglass-o:before{content:"\f250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-hourglass:before{content:"\f254"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\f255"}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:"\f256"}.fa-hand-scissors-o:before{content:"\f257"}.fa-hand-lizard-o:before{content:"\f258"}.fa-hand-spock-o:before{content:"\f259"}.fa-hand-pointer-o:before{content:"\f25a"}.fa-hand-peace-o:before{content:"\f25b"}.fa-trademark:before{content:"\f25c"}.fa-registered:before{content:"\f25d"}.fa-creative-commons:before{content:"\f25e"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-tripadvisor:before{content:"\f262"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-get-pocket:before{content:"\f265"}.fa-wikipedia-w:before{content:"\f266"}.fa-safari:before{content:"\f267"}.fa-chrome:before{content:"\f268"}.fa-firefox:before{content:"\f269"}.fa-opera:before{content:"\f26a"}.fa-internet-explorer:before{content:"\f26b"}.fa-tv:before,.fa-television:before{content:"\f26c"}.fa-contao:before{content:"\f26d"}.fa-500px:before{content:"\f26e"}.fa-amazon:before{content:"\f270"}.fa-calendar-plus-o:before{content:"\f271"}.fa-calendar-minus-o:before{content:"\f272"}.fa-calendar-times-o:before{content:"\f273"}.fa-calendar-check-o:before{content:"\f274"}.fa-industry:before{content:"\f275"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-map-o:before{content:"\f278"}.fa-map:before{content:"\f279"}.fa-commenting:before{content:"\f27a"}.fa-commenting-o:before{content:"\f27b"}.fa-houzz:before{content:"\f27c"}.fa-vimeo:before{content:"\f27d"}.fa-black-tie:before{content:"\f27e"}.fa-fonticons:before{content:"\f280"}.fa-reddit-alien:before{content:"\f281"}.fa-edge:before{content:"\f282"}.fa-credit-card-alt:before{content:"\f283"}.fa-codiepie:before{content:"\f284"}.fa-modx:before{content:"\f285"}.fa-fort-awesome:before{content:"\f286"}.fa-usb:before{content:"\f287"}.fa-product-hunt:before{content:"\f288"}.fa-mixcloud:before{content:"\f289"}.fa-scribd:before{content:"\f28a"}.fa-pause-circle:before{content:"\f28b"}.fa-pause-circle-o:before{content:"\f28c"}.fa-stop-circle:before{content:"\f28d"}.fa-stop-circle-o:before{content:"\f28e"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-hashtag:before{content:"\f292"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-percent:before{content:"\f295"}.fa-gitlab:before{content:"\f296"}.fa-wpbeginner:before{content:"\f297"}.fa-wpforms:before{content:"\f298"}.fa-envira:before{content:"\f299"}.fa-universal-access:before{content:"\f29a"}.fa-wheelchair-alt:before{content:"\f29b"}.fa-question-circle-o:before{content:"\f29c"}.fa-blind:before{content:"\f29d"}.fa-audio-description:before{content:"\f29e"}.fa-volume-control-phone:before{content:"\f2a0"}.fa-braille:before{content:"\f2a1"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-asl-interpreting:before,.fa-american-sign-language-interpreting:before{content:"\f2a3"}.fa-deafness:before,.fa-hard-of-hearing:before,.fa-deaf:before{content:"\f2a4"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-signing:before,.fa-sign-language:before{content:"\f2a7"}.fa-low-vision:before{content:"\f2a8"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-pied-piper:before{content:"\f2ae"}.fa-first-order:before{content:"\f2b0"}.fa-yoast:before{content:"\f2b1"}.fa-themeisle:before{content:"\f2b2"}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:"\f2b3"}.fa-fa:before,.fa-font-awesome:before{content:"\f2b4"}.fa-handshake-o:before{content:"\f2b5"}.fa-envelope-open:before{content:"\f2b6"}.fa-envelope-open-o:before{content:"\f2b7"}.fa-linode:before{content:"\f2b8"}.fa-address-book:before{content:"\f2b9"}.fa-address-book-o:before{content:"\f2ba"}.fa-vcard:before,.fa-address-card:before{content:"\f2bb"}.fa-vcard-o:before,.fa-address-card-o:before{content:"\f2bc"}.fa-user-circle:before{content:"\f2bd"}.fa-user-circle-o:before{content:"\f2be"}.fa-user-o:before{content:"\f2c0"}.fa-id-badge:before{content:"\f2c1"}.fa-drivers-license:before,.fa-id-card:before{content:"\f2c2"}.fa-drivers-license-o:before,.fa-id-card-o:before{content:"\f2c3"}.fa-quora:before{content:"\f2c4"}.fa-free-code-camp:before{content:"\f2c5"}.fa-telegram:before{content:"\f2c6"}.fa-thermometer-4:before,.fa-thermometer:before,.fa-thermometer-full:before{content:"\f2c7"}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-thermometer-2:before,.fa-thermometer-half:before{content:"\f2c9"}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:"\f2ca"}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:"\f2cb"}.fa-shower:before{content:"\f2cc"}.fa-bathtub:before,.fa-s15:before,.fa-bath:before{content:"\f2cd"}.fa-podcast:before{content:"\f2ce"}.fa-window-maximize:before{content:"\f2d0"}.fa-window-minimize:before{content:"\f2d1"}.fa-window-restore:before{content:"\f2d2"}.fa-times-rectangle:before,.fa-window-close:before{content:"\f2d3"}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:"\f2d4"}.fa-bandcamp:before{content:"\f2d5"}.fa-grav:before{content:"\f2d6"}.fa-etsy:before{content:"\f2d7"}.fa-imdb:before{content:"\f2d8"}.fa-ravelry:before{content:"\f2d9"}.fa-eercast:before{content:"\f2da"}.fa-microchip:before{content:"\f2db"}.fa-snowflake-o:before{content:"\f2dc"}.fa-superpowers:before{content:"\f2dd"}.fa-wpexplorer:before{content:"\f2de"}.fa-meetup:before{content:"\f2e0"}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}
5 |
--------------------------------------------------------------------------------
/docs/css/customstyles.css:
--------------------------------------------------------------------------------
1 | .anchor-link {
2 | display: none;
3 | }
4 |
5 | body {
6 | font-size:15px;
7 | }
8 |
9 | .bs-callout {
10 | padding: 20px;
11 | margin: 20px 0;
12 | border: 1px solid #eee;
13 | border-left-width: 5px;
14 | border-radius: 3px;
15 | }
16 | .bs-callout h4 {
17 | margin-top: 0;
18 | margin-bottom: 5px;
19 | }
20 | .bs-callout p:last-child {
21 | margin-bottom: 0;
22 | }
23 | .bs-callout code {
24 | border-radius: 3px;
25 | }
26 | .bs-callout+.bs-callout {
27 | margin-top: -5px;
28 | }
29 | .bs-callout-default {
30 | border-left-color: #777;
31 | }
32 | .bs-callout-default h4 {
33 | color: #777;
34 | }
35 | .bs-callout-primary {
36 | border-left-color: #428bca;
37 | }
38 | .bs-callout-primary h4 {
39 | color: #428bca;
40 | }
41 | .bs-callout-success {
42 | border-left-color: #5cb85c;
43 | }
44 | .bs-callout-success h4 {
45 | color: #5cb85c;
46 | }
47 | .bs-callout-danger {
48 | border-left-color: #d9534f;
49 | }
50 | .bs-callout-danger h4 {
51 | color: #d9534f;
52 | }
53 | .bs-callout-warning {
54 | border-left-color: #f0ad4e;
55 | }
56 | .bs-callout-warning h4 {
57 | color: #f0ad4e;
58 | }
59 | .bs-callout-info {
60 | border-left-color: #5bc0de;
61 | }
62 | .bs-callout-info h4 {
63 | color: #5bc0de;
64 | }
65 |
66 |
67 | .gi-2x{font-size: 2em;}
68 | .gi-3x{font-size: 3em;}
69 | .gi-4x{font-size: 4em;}
70 | .gi-5x{font-size: 5em;}
71 |
72 |
73 | .breadcrumb > .active {color: #777 !important;}
74 |
75 | /* make room for the nav bar */
76 | h1[id]
77 | /*,h2[id],
78 | h3[id],
79 | h4[id],
80 | h5[id],
81 | h6[id],
82 | dt[id]*/
83 | {
84 | padding-top: 60px;
85 | margin-top: -40px
86 | }
87 |
88 | .output_html a{
89 | font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
90 | margin: 25px 0px;
91 | display: block;
92 | padding: 9.5px;
93 | font-size: 13px;
94 | line-height: 1.42857143;
95 | color: #333;
96 | word-break: break-all;
97 | word-wrap: break-word;
98 | background-color: #F5F5F5;
99 | border: 1px solid #FFA500;
100 | border-radius: 4px;
101 | white-space: pre-wrap;
102 | box-sizing: border-box;
103 | overflow: auto;
104 | }
105 |
106 | .col-md-1, .col-md-10, .col-md-11, .col-md-12, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9 {
107 | float: left;
108 | }
109 |
110 | .col-md-9 {
111 | width: 75%;
112 | }
113 |
114 | /* From: https://www.w3schools.com/howto/tryit.asp?filename=tryhow_css_download_button' */
115 | .cstm_btn a{
116 | background-color: DodgerBlue;
117 | border: none;
118 | color: white;
119 | padding: 12px 30px;
120 | cursor: pointer;
121 | font-size: 20px;
122 | box-sizing: 15px;
123 | position: absolute;
124 | }
125 |
126 | /* Darker background on mouse-over */
127 | .cstm_btn a:hover {
128 | background-color: RoyalBlue;
129 | }
130 |
131 | .container #notebook-container{
132 | width: 100%;
133 | box-sizing: border-box;
134 | }
135 |
136 | .post-content img {
137 | margin: 12px 0px 3px 0px;
138 | width: auto;
139 | height: auto;
140 | max-width: 100%;
141 | max-height: 100%;
142 | }
143 |
144 | .post-content ol li, .post-content ul li {
145 | margin: 10px 0px;
146 | }
147 |
148 | .pageSummary {
149 | font-size:13px;
150 | display:block;
151 | margin-bottom:15px;
152 | padding-left:20px;
153 | }
154 |
155 | .post-summary {
156 | margin-bottom:12px;
157 | }
158 |
159 | .bs-example{
160 | margin: 20px;
161 | }
162 |
163 | .breadcrumb li {
164 | color: gray;
165 | }
166 |
167 | table {
168 | background-color: transparent;
169 | }
170 | caption {
171 | padding-top: 8px;
172 | padding-bottom: 8px;
173 | color: #777;
174 | text-align: left;
175 | }
176 | th {
177 | text-align: left;
178 | }
179 | table {
180 | max-width: 90%;
181 | margin-bottom: 20px;
182 | border: 1px solid #dedede;
183 | }
184 |
185 | table > thead > tr > th,
186 | table > tbody > tr > th,
187 | table > tfoot > tr > th,
188 | table > thead > tr > td,
189 | table > tbody > tr > td,
190 | table > tfoot > tr > td {
191 | padding: 8px;
192 | line-height: 1.42857143;
193 | vertical-align: top;
194 | border-top: 1px solid #ddd;
195 | }
196 | table > thead > tr > th {
197 | vertical-align: bottom;
198 | border-bottom: 2px solid #ddd;
199 | text-transform: none;
200 | background-color: #777;
201 | color: white;
202 | text-align: left;
203 | }
204 | table > caption + thead > tr:first-child > th,
205 | table > colgroup + thead > tr:first-child > th,
206 | table > thead:first-child > tr:first-child > th,
207 | table > caption + thead > tr:first-child > td,
208 | table > colgroup + thead > tr:first-child > td,
209 | table > thead:first-child > tr:first-child > td {
210 | border-top: 0;
211 | }
212 |
213 | table > tbody > tr:nth-of-type(odd) {
214 | background-color: #f9f9f9;
215 | }
216 |
217 | table col[class*="col-"] {
218 | position: static;
219 | display: table-column;
220 | float: none;
221 | }
222 | table td[class*="col-"],
223 | table th[class*="col-"] {
224 | position: static;
225 | display: table-cell;
226 | float: none;
227 | }
228 |
229 | table tr td {
230 | hyphens: auto;
231 | }
232 |
233 |
234 | p.external a {
235 | text-align:right;
236 | font-size:12px;
237 | color: #0088cc;
238 | display:inline;
239 | }
240 |
241 | #definition-box-container div a.active {
242 | font-weight: bold;
243 | }
244 | p.post-meta {font-size: 80%; color: #777;}
245 |
246 | .entry-date{font-size:14px;font-size:0.875rem;line-height:1.71429;margin-bottom:0;text-transform:uppercase;}
247 |
248 | /* search area */
249 | #search-demo-container ul#results-container {
250 | list-style: none;
251 | font-size: 12px;
252 | background-color: white;
253 | position: absolute;
254 | top: 40px; /* if you change anything about the nav, you'll prob. need to reset the top and left values here.*/
255 | left: 20px;
256 | z-index: -1;
257 | width:223px;
258 | border-left: 1px solid #dedede;
259 | }
260 |
261 |
262 | ul#results-container a {
263 | background-color: transparent;
264 | }
265 |
266 | ul#results-container a:hover {
267 | color: black;
268 | }
269 |
270 |
271 | #search-demo-container a:hover {
272 | color: black;
273 | }
274 | #search-input {
275 | padding: .5em;
276 | margin-left:20px;
277 | width:20em;
278 | font-size: 0.8em;
279 | -webkit-box-sizing: border-box;
280 | -moz-box-sizing: border-box;
281 | box-sizing: border-box;
282 | margin-top:10px;
283 | }
284 | /* end search */
285 |
286 | .filter-options {
287 | margin-bottom: 20px;
288 | }
289 | .filter-options button {
290 | margin: 3px;
291 | }
292 |
293 | a.source_link {
294 | float:right;
295 | font-size:15px;
296 | font-weight:normal;
297 | }
298 |
299 | div#toc ul {
300 | font-size: 90%;
301 | background-color: whitesmoke;
302 | padding: 5px;
303 | border-radius: 5px;
304 | max-width: 450px;
305 | color: gray;
306 | list-style-type: none;
307 | }
308 |
309 | /* when using relative fonts like 0.9em or 90%, remember to then set the nested items to 1em or 100%, otherwise each level will get smaller and smaller and less readable */
310 | div#toc ul li {
311 | margin: 8px 0px 8px 22px;
312 | font-size: 100%;
313 | list-style-type: none;
314 | }
315 |
316 | div#toc ul li ul {
317 | font-size: 100%;
318 | padding-left:30px;
319 | padding-top: 0px;
320 | padding-bottom: 0px;
321 | list-style-type: none;
322 | }
323 |
324 | div#toc ul li ul li.hide_content::before {
325 | content: none;
326 | }
327 |
328 | div#toc >ul::before {
329 | content: "Table of Contents";
330 | font-weight: 500;
331 | color: #555;
332 | text-align:center;
333 | margin-left:auto;
334 | margin-right:auto;
335 | width:70px;
336 | padding-top:150px;
337 | padding-bottom:40px;
338 | padding-left:10px;
339 | }
340 |
341 | li.dropdownActive a {
342 | font-weight: bold;
343 | }
344 |
345 |
346 | .post-content a.fa-rss {
347 | color: orange;
348 | }
349 |
350 |
351 | .navbar-inverse .navbar-nav > li > a {
352 | background-color: transparent;
353 | margin-top:10px;
354 | }
355 |
356 | .post-content .rssfeedLink {
357 | color: #248EC2;
358 | }
359 |
360 | footer {
361 | font-size: smaller;
362 | }
363 |
364 | /* FAQ page */
365 | #accordion .panel-heading {
366 | font-size: 12px;
367 | }
368 |
369 | a.accordion-toggle, a.accordion-collapsed {
370 | font-size: 14px;
371 | text-decoration: none;
372 | }
373 |
374 | /* navgoco sidebar styles (customized) */
375 | .nav, .nav ul, .nav li {
376 | list-style: none;
377 | }
378 |
379 | .nav ul {
380 | padding: 0;
381 | /*margin: 0 0 0 18px;*/
382 | margin:0px;
383 | }
384 |
385 | .nav {
386 | /* padding: 4px;*/
387 | padding:0px;
388 | margin: 0px;
389 | }
390 |
391 | .nav > li {
392 | margin: 1px 0;
393 | }
394 |
395 | .nav > li li {
396 | margin: 2px 0;
397 | }
398 |
399 | .nav a {
400 | color: #333;
401 | display: block;
402 | outline: none;
403 | /*-webkit-border-radius: 4px;
404 | -moz-border-radius: 4px;
405 | border-radius: 4px;*/
406 | text-decoration: none;
407 | }
408 |
409 | .nav li > a > span {
410 | float: right;
411 | font-size: 19px;
412 | font-weight: bolder;
413 | }
414 |
415 |
416 | .nav li > a > span:after {
417 | content: '\25be';
418 | }
419 | .nav li.active > a > span:after {
420 | content: '\25b4';
421 | }
422 |
423 | .nav a:hover, .nav li.active > a {
424 | background-color: #8D8D8D;
425 | color: #f5f5f5;
426 | }
427 |
428 | .nav > li.active > a {
429 | background-color: #347DBE;
430 | }
431 |
432 | .nav li a {
433 | font-size: 12px;
434 | line-height: 18px;
435 | padding: 2px 10px;
436 | background-color: #f1f1f1;
437 | }
438 |
439 | .nav > li > a {
440 | font-size: 14px;
441 | line-height: 20px;
442 | padding: 4px 10px;
443 | }
444 |
445 | ul#mysidebar {
446 | border-radius:0px;
447 | }
448 |
449 | .nav ul li ul li a {
450 | padding-left:40px;
451 | }
452 |
453 | .nav li.thirdlevel > a {
454 | color: #248EC2;
455 | font-weight:bold;
456 | padding-left:20px;
457 | background-color: whitesmoke !important;
458 | }
459 |
460 |
461 | .nav ul li a {
462 | background-color: #FAFAFA;
463 | }
464 |
465 | .nav li a {
466 | padding-right:10px;
467 | }
468 |
469 | .nav li a:hover {
470 | background-color: #8D8D8D;
471 | }
472 |
473 | .nav ul li a {
474 | border-top:1px solid whitesmoke;
475 | padding-left:10px;
476 | }
477 | /* end sidebar */
478 |
479 | .navbar-inverse .navbar-nav > .active > a, .navbar-inverse .navbar-nav > .active > a:hover, .navbar-inverse .navbar-nav > .active > a:focus {
480 | border-radius:5px;
481 | }
482 |
483 | .navbar-inverse .navbar-nav>.open>a, .navbar-inverse .navbar-nav>.open>a:focus, .navbar-inverse .navbar-nav>.open>a:hover {
484 | border-radius: 5px;
485 | }
486 |
487 | span.projectTitle {
488 | font-family: Helvetica;
489 | font-weight: bold;
490 | }
491 |
492 | .footer {
493 | text-align: right;
494 | }
495 |
496 | .footerMeta {
497 | background-color: whitesmoke;
498 | padding: 10px;
499 | max-width: 250px;
500 | border-radius: 5px;
501 | margin-top: 50px;
502 | font-style:italic;
503 | font-size:12px;
504 | }
505 |
506 | img.screenshotSmall {
507 | max-width: 300px;
508 | }
509 |
510 |
511 | dl dt p {
512 | margin-left:20px;
513 | }
514 |
515 |
516 | dl dd {
517 | margin-top:10px;
518 | margin-bottom:10px;
519 | }
520 |
521 | dl.dl-horizontal dd {
522 | padding-top: 20px;
523 | }
524 |
525 | figcaption {
526 |
527 | padding-bottom:12px;
528 | padding-top:6px;
529 | max-width: 90%;
530 | margin-bottom:20px;
531 | font-style: italic;
532 | color: gray;
533 |
534 | }
535 |
536 | .testing {
537 | color: orange;
538 | }
539 |
540 | .preference {
541 | color: red;
542 | }
543 |
544 |
545 | table.dataTable thead {
546 | background-color: #444;
547 | }
548 | table td {
549 | hyphens: auto;
550 | }
551 |
552 | section table tr.success {
553 | background-color: #dff0d8 !important;
554 | }
555 |
556 | table tr.info {
557 | background-color: #d9edf7 !important;
558 | }
559 |
560 | section table tr.warning, table tr.testing, table tr.testing > td.sorting_1 {
561 | background-color: #fcf8e3 !important;
562 | }
563 | section table tr.danger, table tr.preference, table tr.preference > td.sorting_1 {
564 | background-color: #f2dede !important;
565 | }
566 |
567 | .orange {
568 | color: orange;
569 | }
570 |
571 | table.profile thead tr th {
572 | background-color: #248ec2;
573 | }
574 |
575 | table.request thead tr th {
576 | background-color: #ED1951;
577 | }
578 |
579 | .audienceLabel {
580 | margin: 10px;
581 | float: right;
582 | border:1px solid #dedede;
583 | padding:7px;
584 | }
585 |
586 | .prefaceAudienceLabel {
587 | color: gray;
588 | text-align: center;
589 | margin:5px;
590 | }
591 | span.myLabel {
592 | padding-left:10px;
593 | padding-right:10px;
594 | }
595 |
596 | button.cursorNorm {
597 | cursor: default;
598 | }
599 |
600 | a.dropdown-toggle, .navbar-inverse .navbar-nav > li > a {
601 | margin-left: 10px;
602 | }
603 |
604 | hr.faded {
605 | border: 0;
606 | height: 1px;
607 | background-image: -webkit-linear-gradient(left, rgba(0,0,0,0), rgba(0,0,0,0.75), rgba(0,0,0,0));
608 | background-image: -moz-linear-gradient(left, rgba(0,0,0,0), rgba(0,0,0,0.75), rgba(0,0,0,0));
609 | background-image: -ms-linear-gradient(left, rgba(0,0,0,0), rgba(0,0,0,0.75), rgba(0,0,0,0));
610 | background-image: -o-linear-gradient(left, rgba(0,0,0,0), rgba(0,0,0,0.75), rgba(0,0,0,0));
611 | }
612 |
613 | hr.shaded {
614 | height: 12px;
615 | border: 0;
616 | margin-top: 70px;
617 | background: white;
618 | width: 100%;
619 | margin-bottom: 10px;
620 | }
621 |
622 | .fa-6x{font-size:900%;}
623 | .fa-7x{font-size:1100%;}
624 | .fa-8x{font-size:1300%;}
625 | .fa-9x{font-size:1500%;}
626 | .fa-10x{font-size:1700%;}
627 |
628 | i.border {
629 | padding: 10px 20px;
630 | background-color: whitesmoke;
631 | }
632 |
633 | a[data-toggle] {
634 | color: #248EC2;
635 | }
636 |
637 | .summary {
638 | font-size:120%;
639 | color: #808080;
640 | margin:20px 0px 20px 0px;
641 | border-left: 5px solid #ED1951;
642 | padding-left: 10px;
643 |
644 | }
645 |
646 | a.fa.fa-envelope-o.mailto {
647 | font-weight: 600;
648 | }
649 |
650 | h3 {color: #ED1951; font-weight:normal; font-size:130%;}
651 | h4 {color: #000000; font-weight:normal; font-size:120%; font-weight:bold;}
652 |
653 | .alert, .callout {
654 | overflow: hidden;
655 | }
656 |
657 | .nav-tabs > li.active > a, .nav-tabs > li.active > a:hover, .nav-tabs > li.active > a:focus {
658 | background-color: #248ec2;
659 | color: white;
660 | }
661 |
662 | ol li ol li {list-style-type: lower-alpha;}
663 | ol li ul li {list-style-type: disc;}
664 |
665 | li img {clear:both; }
666 |
667 | div#toc ul li ul li {
668 | list-style-type: none;
669 | margin: 5px 0px 0px 0px;
670 | }
671 |
672 | .tab-content {
673 | padding: 15px;
674 | background-color: #FAFAFA;
675 | }
676 |
677 | span.tagTitle {font-weight: 500;}
678 |
679 | li.activeSeries {
680 | font-weight: bold;
681 | }
682 |
683 | .seriesContext .dropdown-menu li.active {
684 | font-weight: bold;
685 | margin-left: 43px;
686 | font-size:18px;
687 | }
688 |
689 | .alert-warning {
690 | color: #444;
691 | }
692 |
693 | div.alert code, h2 code {
694 | background-color: transparent !important;
695 | }
696 | /* without this, the links in these notes aren't visible.*/
697 | .alert a {
698 | text-decoration: underline;
699 | }
700 |
701 | div.tags {padding: 10px 5px;}
702 |
703 | .tabLabel {
704 | font-weight: normal;
705 | }
706 |
707 | hr {
708 | background: #999;
709 | margin: 30px 0px;
710 | width: 90%;
711 | margin-left: auto;
712 | margin-right: auto;
713 | }
714 |
715 | button.cursorNorm {
716 | cursor: pointer;
717 | }
718 |
719 | h2 {
720 | font-size:24px;
721 | line-height:29px;
722 | border-top: 3px solid blue;
723 | padding-top: 5px;
724 | }
725 |
726 | span.otherProgrammingLanguages {
727 | font-style: normal;
728 | }
729 |
730 | a[data-toggle="tooltip"] {
731 | color: #649345;
732 | font-style: italic;
733 | cursor: default;
734 | }
735 |
736 | .seriesNext, .seriesContext {
737 | margin-top: 15px;
738 | margin-bottom: 15px;
739 | }
740 |
741 | .seriescontext ol li {
742 | list-style-type: upper-roman;
743 | }
744 |
745 | ol.series li {
746 | list-style-type: decimal;
747 | margin-left: 40px;
748 | padding-left: 0px;
749 | }
750 |
751 | .siteTagline {
752 | font-size: 200%;
753 | font-weight: bold;
754 | color: silver;
755 | font-family: monospace;
756 | text-align: center;
757 | line-height: 10px;
758 | margin: 20px 0px;
759 | display: block;
760 | }
761 |
762 | .versionTagline {
763 | text-align: center;
764 | margin-bottom: 20px;
765 | font-family: courier;
766 | color: silver;
767 | color: #444;
768 | display:block;
769 | }
770 |
771 | /* not sure if using this ...*/
772 | .navbar-inverse .navbar-collapse, .navbar-inverse .navbar-form {
773 | border-color: #248ec2 !important;
774 | }
775 |
776 | #mysidebar .nav ul {
777 | background-color: #FAFAFA;
778 | }
779 | .nav ul.series li {
780 | list-style: decimal;
781 | font-size:12px;
782 | }
783 |
784 | .nav ul.series li a:hover {
785 | background-color: gray;
786 | }
787 | .nav ul.series {
788 | padding-left: 30px;
789 | }
790 |
791 | .nav ul.series {
792 | background-color: #FAFAFA;
793 | }
794 |
795 | /*
796 | a.dropdown-toggle.otherProgLangs {
797 | color: #f7e68f !important;
798 | }
799 | */
800 |
801 | span.muted {color: #666;}
802 |
803 | table code {background-color: transparent;}
804 |
805 | .highlight .err {
806 | color: #a61717;
807 | background-color: transparent !important;
808 | }
809 |
810 | table p {
811 | margin-top: 12px;
812 | margin-bottom: 12px;
813 | }
814 |
815 | pre, table code {
816 | white-space: pre-wrap; /* css-3 */
817 | white-space: -moz-pre-wrap; /* Mozilla, since 1999 */
818 | white-space: -pre-wrap; /* Opera 4-6 */
819 | white-space: -o-pre-wrap; /* Opera 7 */
820 | word-wrap: break-word; /* Internet Explorer 5.5+ */
821 | }
822 |
823 | pre {
824 | margin: 25px 0px;
825 | }
826 |
827 | #json-box-container pre {
828 | margin: 0px;
829 | }
830 |
831 | .video-js {
832 | margin: 30px 0px;
833 | }
834 |
835 | video {
836 | display: block;
837 | margin: 30px 0px;
838 | border: 1px solid #c0c0c0;
839 | }
840 |
841 |
842 | p.required, p.dataType {display: block; color: #c0c0c0; font-size: 80%; margin-left:4px;}
843 |
844 | dd {margin-left:20px;}
845 |
846 | .post-content img.inline {
847 | margin:0px;
848 | margin-bottom:6px;
849 | }
850 | .panel-heading {
851 | font-weight: bold;
852 | }
853 |
854 | .note code, .alert code, .warning code, div#toc code, h2 code, h3 code, h4 code {
855 | color: inherit;
856 | padding: 0px;
857 | }
858 |
859 | .alert {
860 | margin-bottom:10px;
861 | margin-top:10px;
862 | }
863 |
864 | a.accordion-toggle {
865 | font-style: normal;
866 | }
867 |
868 | span.red {
869 | color: red;
870 | font-family: Monaco, Menlo, Consolas, "Courier New", monospace;
871 | }
872 |
873 | h3.codeExplanation {
874 | font-size:18px;
875 | font-style:normal;
876 | color: black;
877 | line-height: 24px;
878 | }
879 |
880 | span.soft {
881 | color: #c0c0c0;
882 | }
883 |
884 | .githubEditButton {
885 | margin-bottom:7px;
886 | }
887 |
888 | .endpoint {
889 | padding: 15px;
890 | background-color: #f0f0f0;
891 | font-family: courier;
892 | font-size: 110%;
893 | margin: 20px 0px;
894 | color: #444;
895 | }
896 |
897 | .parameter {
898 | font-family: courier;
899 | color: red !important;
900 | }
901 |
902 | .formBoundary {
903 | border: 1px solid gray;
904 | padding: 15px;
905 | margin: 15px 0px;
906 | background-color: whitesmoke;
907 | }
908 |
909 | @media (max-width: 767px) {
910 | .navbar-inverse .navbar-nav .open .dropdown-menu > li > a {
911 | color: #444;
912 | }
913 | }
914 |
915 | @media (max-width: 990px) {
916 | #mysidebar {
917 | position: relative;
918 | }
919 | .col-md-9 {
920 | width: 95%;
921 | }
922 | }
923 |
924 |
925 | @media (min-width: 1000px) {
926 |
927 | ul#mysidebar {
928 | width: 225px;
929 | }
930 | }
931 |
932 | @media (max-width: 900px) {
933 |
934 | ul#mysidebar {
935 | max-width: 100%;
936 | }
937 | }
938 |
939 | .col-md-9 img {
940 | max-width: 100%;
941 | max-height: 100%;
942 | }
943 |
944 |
945 | .post-content img {
946 | margin: 12px 0px 3px 0px;
947 | width: auto;
948 | height: auto;
949 | max-width: 100%;
950 | max-height: 100%;
951 | }
952 | .col-md-9 img {
953 | max-width: 100%;
954 | max-height: 100%;
955 | }
956 |
957 |
958 | .post-content img {
959 | margin: 12px 0px 3px 0px;
960 | width: auto;
961 | height: auto;
962 | max-width: 100%;
963 | max-height: 100%;
964 | }
965 |
966 | .videoThumbs img {
967 | float: left;
968 | margin:15px 15px 15px 0px;
969 | border: 1px solid #dedede;
970 | }
971 |
972 |
973 | @media only screen and (min-width: 900px), only screen and (min-device-width: 900px) {
974 | .col-md-9 img {
975 | max-width: 990px;
976 | max-height: 700px;
977 | }
978 | }
979 |
980 | *:hover > .anchorjs-link {
981 | transition: color .25s linear;
982 | text-decoration: none;
983 | }
984 |
985 | .kbCaption {
986 | color: white;
987 | background-color: #444;
988 | padding:10px;
989 | }
990 |
991 | /* Strip the outbound icon when this class is present */
992 | a[href].noCrossRef::after,
993 | a.no_icon:after
994 | {
995 | content:"" !important;
996 | padding-left: 0;
997 | }
998 |
999 | .btn-default {
1000 | margin-bottom: 10px;
1001 | }
1002 |
1003 | /* algolia search */
1004 |
1005 | .search {
1006 | text-align: left;
1007 | }
1008 | .search input {
1009 | font-size: 20px;
1010 | width: 300px;
1011 | }
1012 | .results {
1013 | margin: auto;
1014 | text-align: left;
1015 | }
1016 | .results ul {
1017 | list-style-type: none;
1018 | padding: 0;
1019 | }
1020 |
1021 | /* algolia */
1022 |
1023 | div.results {
1024 | position: absolute;
1025 | background-color: white;
1026 | width: 100%;
1027 | }
1028 |
1029 | .post-meta {
1030 | font-size: 14px;
1031 | color: #828282;
1032 | }
1033 |
1034 | .post-link {
1035 | font-size: 22px;
1036 | }
1037 |
1038 | .post-list p {
1039 | margin: 10px 0px;
1040 | }
1041 |
1042 | time {
1043 | margin-right: 10px;
1044 | }
1045 |
1046 | p.post-meta time {
1047 | margin-right: 0px;
1048 | }
1049 |
1050 | span.label.label-default {
1051 | background-color: gray;
1052 | }
1053 |
1054 | span.label.label-primary {
1055 | background-color: #f0ad4e;
1056 | }
1057 | .col-lg-12 .nav li a {background-color: white}
1058 |
1059 |
1060 | .nav li.active > a.subfoldersTitle {
1061 | background-color: whitesmoke;
1062 | font-weight: bold;
1063 | color: black;
1064 | }
1065 |
1066 | code {
1067 | color: #1d1f5b;
1068 | background-color: #f3f3f3;
1069 | }
1070 |
1071 | a code {
1072 | color: #0082C2;
1073 | }
1074 |
1075 | table th code {
1076 | color: white;
1077 | }
1078 |
1079 | ol li ul li ol li {
1080 | list-style: decimal;
1081 | }
1082 |
1083 | ol li ul li ol li ul li{
1084 | list-style: disc;
1085 | }
1086 |
1087 | .post-content table th {
1088 | vertical-align: top;
1089 | }
1090 |
1091 | table thead th code.highlighter-rouge {
1092 | background-color: transparent;
1093 | }
1094 |
1095 |
1096 | .box {
1097 | padding: 10px;
1098 | border: 1px solid #888;
1099 | width: 100px;
1100 | height: 80px;
1101 | background-color: #f5f5f5;
1102 | font-family: Arial;
1103 | font-size: 12px;
1104 | hyphens: auto;
1105 | float: left;
1106 | font-size: 12px;
1107 | }
1108 |
1109 | .box:hover {
1110 | background-color: #f0f0f0;
1111 | }
1112 |
1113 | #userMap {
1114 | overflow-x: auto;
1115 | overflow-y: auto;
1116 | padding: 20px;
1117 | min-width: 770px;
1118 | }
1119 |
1120 | #userMap .active {
1121 | background-color: #d6f5d6;
1122 | border:1px solid #555;
1123 | font-weight: bold;
1124 | }
1125 |
1126 | h2.userMapTitle {
1127 | font-family: Arial;
1128 | }
1129 |
1130 | #userMap a:hover {
1131 | text-decoration: none;
1132 | }
1133 |
1134 | div.arrow {
1135 | max-width: 50px;
1136 | margin-left: 15px;
1137 | margin-right: 15px;
1138 | font-size: 20px;
1139 | }
1140 |
1141 | div.content {
1142 | max-width: 110px
1143 | }
1144 |
1145 | #userMap div.arrow, #userMap div.content {
1146 | float: left;
1147 | }
1148 |
1149 | .clearfix {
1150 | clear: both;
1151 | }
1152 |
1153 |
1154 | #userMap div.arrow {
1155 | position: relative;
1156 | top: 30px;
1157 | }
1158 |
1159 | .box1 {
1160 | margin-left:0px;
1161 | }
1162 |
1163 | button.btn.btn-default.btn-lg.modalButton1 {
1164 | margin-left: -20px;
1165 | }
1166 |
1167 | div.box.box1 {
1168 | margin-left: -20px;
1169 | }
1170 |
1171 | #userMap .btn-lg {
1172 | width: 100px;
1173 | height: 80px;
1174 |
1175 | }
1176 |
1177 | #userMap .complexArrow {
1178 | font-size: 22px;
1179 | margin: 0px 10px;
1180 | }
1181 |
1182 |
1183 | #userMap .btn-lg .active {
1184 | background-color: #d6f5d6;
1185 | }
1186 |
1187 | #userMap .btn-lg {
1188 | white-space: pre-wrap; /* css-3 */
1189 | white-space: -moz-pre-wrap; /* Mozilla, since 1999 */
1190 | white-space: -pre-wrap; /* Opera 4-6 */
1191 | white-space: -o-pre-wrap; /* Opera 7 */
1192 | word-wrap: break-word; /* Internet Explorer 5.5+ */
1193 | font-size: 14px;
1194 | }
1195 |
1196 | /*
1197 | * Let's target IE to respect aspect ratios and sizes for img tags containing SVG files
1198 | *
1199 | * [1] IE9
1200 | * [2] IE10+
1201 | */
1202 | /* 1 */
1203 | .ie9 img[src$=".svg"] {
1204 | width: 100%;
1205 | }
1206 | /* 2 */
1207 | @media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {
1208 | img[src$=".svg"] {
1209 | width: 100%;
1210 | }
1211 | }
1212 |
1213 | h4.panel-title {
1214 | padding-top: 0px;
1215 | margin-top: 0px;
1216 | }
1217 |
1218 | /*set navbar breakpoint so that it converts to hamburger earlier */
1219 |
1220 | @media (max-width: 1200px) {
1221 | .navbar-header {
1222 | float: none;
1223 | }
1224 | .navbar-left,.navbar-right {
1225 | float: none !important;
1226 | }
1227 | .navbar-toggle {
1228 | display: block;
1229 | }
1230 | .navbar-collapse {
1231 | border-top: 1px solid transparent;
1232 | }
1233 | .navbar-fixed-top {
1234 | top: 0;
1235 | border-width: 0 0 1px;
1236 | }
1237 | .navbar-collapse.collapse {
1238 | display: none!important;
1239 | }
1240 | .navbar-nav {
1241 | float: none!important;
1242 | margin-top: 7.5px;
1243 | }
1244 | .navbar-nav>li {
1245 | float: none;
1246 | }
1247 | .navbar-nav>li>a {
1248 | padding-top: 10px;
1249 | padding-bottom: 10px;
1250 | }
1251 | .collapse.in{
1252 | display:block !important;
1253 | }
1254 | }
1255 |
1256 | .input_area pre {
1257 | padding-bottom: 3;
1258 | margin-top: 10px;
1259 | background-color: #f5f1e0;
1260 | border: 0px;
1261 | }
1262 | .output_area pre {
1263 | padding-top: 3;
1264 | margin-top: -25px;
1265 | margin-bottom: 10px;
1266 | border: 0px;
1267 | padding-left: 2em;
1268 | }
1269 | .pytest_card {
1270 | padding: 10px 1em 4px 1em;
1271 | background-color: #eef2ff;
1272 | border-radius: 5px;
1273 | margin-bottom: 20px;
1274 | }
1275 | .pytest_card .close {
1276 | color: #000
1277 | }
1278 | blockquote {
1279 | font-family: Menlo,Monaco,Consolas,"Courier New",monospace;
1280 | }
1281 | blockquote code {
1282 | background-color: white;
1283 | }
1284 | h4 code {
1285 | background-color: white;
1286 | }
1287 |
1288 | /* Google Custom Search styling */
1289 |
1290 | #gcs-search-container {
1291 | width: 340px !important; /* ToDo: define width without using absolute px value */
1292 | display: inline-block !important;
1293 | }
1294 |
1295 | .gsc-search-box.gsc-search-box-tools table {
1296 | margin-bottom: 0px !important;
1297 | }
1298 | .gsc-input, .gsc-search-button {
1299 | padding: 0;
1300 | }
1301 | .gsc-control-cse {
1302 | padding: 6px !important;
1303 | }
1304 | input.gsc-input {
1305 | font-size: 12px !important;
1306 | }
1307 |
--------------------------------------------------------------------------------