diff --git a/.circleci/config.yml b/.circleci/config.yml index 563065587..55386c264 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,65 +1,50 @@ - # Python CircleCI 2.0 configuration file - version: 2.1 - jobs: - test: - docker: - - image: circleci/python:3.7.4 +version: 2.1 - working_directory: ~/repo +orbs: + codecov: codecov/codecov@1.0.5 - environment: - JIANT_PROJECT_PREFIX: sample_run - JIANT_DATA_DIR: data - WORD_EMBS_FILE: none - steps: - # Step 1: obtain repo from GitHub - - checkout - # Step 2: restore pip dependencies from cache, keyed on branch and content of setup.py - - restore_cache: - key: deps1-{{ .Branch }}-{{ checksum "setup.py" }} - # Step 3: style check - - run: - name: check style - command: | - pip install --user black==19.3b0 - black . --check --exclude "/(\.eggs|\.git|\.hg|\.mypy_cache|\.nox|\.tox|\.venv|_build|buck-out|build|dist|jiant/modules/cove|venv)/" - # Step 4: get data needed for demo.sh - - run: - name: download demo data - command: | - python scripts/download_glue_data.py --data_dir $JIANT_DATA_DIR --tasks MRPC,STS,SST - python scripts/download_superglue_data.py --data_dir $JIANT_DATA_DIR --tasks CB - # Step 5: create virtual env and install dependencies - - run: - name: install dependencies - command: | +jobs: + test: + docker: + - image: python:3.7 + steps: + - checkout + - restore_cache: + key: -v3-{{ checksum "requirements-dev.txt" }} + - run: + name: Install dependencies + command: | python3 -m venv venv source venv/bin/activate - pip install -e ~/repo - pip install nose2 - # Step 6: cache dependencies for future CI jobs - - save_cache: - key: deps1-{{ .Branch }}-{{ checksum "setup.py" }} - paths: + pip install -r requirements-dev.txt + - save_cache: + key: -v3-{{ checksum "requirements-dev.txt" }} + paths: - "venv" - # Step 7: demo.sh run test - - run: - name: running demo.sh - command: | + - run: + name: black formatting check + command: | source venv/bin/activate - python -m nltk.downloader perluniprops nonbreaking_prefixes punkt - python -m spacy download en - python main.py --config_file jiant/config/demo.conf - python main.py --config_file jiant/config/demo.conf --overrides "do_pretrain = 0, do_target_task_training = 0, load_model = 1" - # Step 8: run tests - - run: - name: run tests - command: | + black --check jiant/ + - run: + name: flake8 + command: | source venv/bin/activate - mkdir ~/repo/test_output - nose2 -v - workflows: - version: 2 - test: - jobs: - - test + flake8 --docstring-convention google jiant/ + - run: + name: Unit Tests + command: | + source venv/bin/activate + pytest + - run: + name: Coverage Report + command: | + source venv/bin/activate + pytest --cov-report=xml --cov=jiant tests/ + - codecov/upload: + file: coverage.xml + +workflows: + build: + jobs: + - test diff --git a/.flake8 b/.flake8 new file mode 100644 index 000000000..4d3d62a48 --- /dev/null +++ b/.flake8 @@ -0,0 +1,24 @@ +[flake8] +max-line-length = 100 + +ignore = + # "these rules don't play well with black", from AllenNLP + E203 # whitespace before : + W503 # line break before binary operatori + # these are docstring-related ignores: + D100 # Missing docstring in public module + D101 # Missing docstring in public class + D102 # Missing docstring in public method + D103 # Missing docstring in public function + D104 # Missing docstring in public package + D105 # Missing docstring in magic method + D107 # Missing docstring in __init__ + D400 # First line should end with a period + D401 # First line should be in imperative mood; try rephrasing + D415 # First line should end with a period, question mark, or exclamation point + D205 # 1 blank line required between summary line and description + +exclude = + examples/** + tests/** + jiant/ext/allennlp.py # excluded to avoid modifying code copied from AllenNLP. diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 000000000..e75a3c22b --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,25 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +1. Tell use which version of `jiant` you're using +2. Describe the environment where you're using `jiant`, e.g, "2 P40 GPUs" +3. Provide the experiment config artifact (e.g., `defaults.conf`) + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 000000000..bbcbbe7d6 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: '' +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. diff --git a/.github/stale.yml b/.github/stale.yml new file mode 100644 index 000000000..dc90e5a1c --- /dev/null +++ b/.github/stale.yml @@ -0,0 +1,17 @@ +# Number of days of inactivity before an issue becomes stale +daysUntilStale: 60 +# Number of days of inactivity before a stale issue is closed +daysUntilClose: 7 +# Issues with these labels will never be considered stale +exemptLabels: + - pinned + - security +# Label to use when marking an issue as stale +staleLabel: wontfix +# Comment to post when marking an issue as stale. Set to `false` to disable +markComment: > + This issue has been automatically marked as stale because it has not had + recent activity. It will be closed if no further activity occurs. Thank you + for your contributions. +# Comment to post when closing a stale issue. Set to `false` to disable +closeComment: false diff --git a/.gitignore b/.gitignore index 2a4ca4449..7114a35bc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,18 +1,128 @@ -*.pyc -*.swp -*.log -*.*~ -glue_data/ -user_config.sh -.idea -.ipynb_checkpoints/ -perluniprops/ -.DS_Store - -# package/distribution artifacts +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python build/ +develop-eggs/ dist/ +downloads/ +eggs/ .eggs/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +pip-wheel-metadata/ +share/python-wheels/ *.egg-info/ +.installed.cfg *.egg -pip-wheel-metadata/ +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +.python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a88a7a20f..8195945a9 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,10 +1,10 @@ repos: - - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v2.1.0 +- repo: https://github.com/ambv/black + rev: stable hooks: - - id: trailing-whitespace - - id: check-yaml - - repo: https://github.com/ambv/black - rev: 19.3b0 + - id: black + language_version: python3.7 +- repo: https://gitlab.com/pycqa/flake8 + rev: 3.7.9 hooks: - - id: black + - id: flake8 diff --git a/CODEOWNERS b/CODEOWNERS index 3bd6e7629..ebfa8e33b 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -1,2 +1,5 @@ -# See https://blog.github.com/2017-07-06-introducing-code-owners/ -* @W4ngatang @iftenney @sleepinyourhat @pruksmhc @pyeres +# These owners will be the default owners for everything in +# the repo. Unless a later match takes precedence, +# @global-owner1 and @global-owner2 will be requested for +# review when someone opens a pull request. +* @zphang @jeswan @HaokunLiu diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index bf99fefe4..73a48c91d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,31 +1,25 @@ -# Contributing to `jiant` +## Contributing to `jiant` -Thanks for contributing to `jiant`! :+1: +Thanks for considering contributing to `jiant`! :+1: -Please review the guidelines below before opening a PR. - -### PR and review process guidelines: +#### Guidelines for a successful PR review process: 1. Choose a descriptive PR title (“Adding SNLI Task” rather than “add task”). -2. In the PR description field provide a summary that explains the motivation for the changes, and link to any relevant GitHub issues related to the PR. +2. In the PR description field provide a summary explaining the motivation for the changes, and link to any related issues. 3. PRs should address only one issue (or a few very closely related issues). -4. While your PR is a work in progress (WIP), use GitHub’s [Draft PR feature](https://github.blog/2019-02-14-introducing-draft-pull-requests/) to provide visibility without requesting a review (publishing a draft PR while your changes are a WIP helps organize/invite comments on proposed changes, and avoids duplication of work). -5. Before requesting review, make sure your code passes tests: - 1. Run unit tests locally using `python -m unittest discover tests/` - 2. Run formatting tests locally with `black {source_file_or_dir}`, or, after installing all jiant requirements and activating the environment, you can run `pre-commit install` so that black checking and reformatting runs automatically before committing your staged changes. - 3. For involved changes, run a minimal experiment (e.g., with “max_vals=1 and val_interval=10”) to check that your changes don’t break at runtime. -6. Once your PR is ready for review, in your Draft PR press “Ready for review”. This will invite code owners to provide reviews, and makes the branch mergeable. +4. While your PR is a work in progress (WIP), use the [Draft PR feature](https://github.blog/2019-02-14-introducing-draft-pull-requests/) to provide visibility without requesting a review. +5. Once your PR is ready for review, in your Draft PR press “Ready for review”. -### Test and documentation guidelines: -1. Tests: Test coverage and testing methods are expected to vary by PR. Test plans should be proposed/discussed early in the PR process. Except in special cases... - * Bug fixes should be paired with a test and/or other validations demonstrating that the bug has been squashed. - * Changes introducing a new feature should come with related unit tests. - * Changes introducing a new task should come with performance benchmark tests demonstrating that the code can roughly reproduce published performance numbers for that task. - * Changes to existing code are expected to come with some documented effort to test for related regressions. In cases where changes affect code that does not have high test coverage, this might involve designing validations and documenting them in the PR thread. If you’re unsure what validations are necessary, ping a code owner for guidance. -2. Documentation: Public functions and methods should be documented with [numpy-style docstrings](https://numpydoc.readthedocs.io/en/latest/format.html). If you’re making a major change to a public function/method that does not already have a docstring, you should add one. +#### Requirements for pull requests (PR) into `jiant`'s master branch: +1. Requirements applied by the automated build system: + 1. black formatting check + 2. flake8 check for style and documentation + 3. pytest unit tests +2. Requirements for successful code reviews: + 1. Code changes must be paired with effective tests. + 2. PRs adding or modifying code must make appropriate changes to related documentation (using [google style](https://google.github.io/styleguide/pyguide.html)). -### Additional guidelines and helpful reminders for specific types of PRs: -* For PRs that change package dependencies, update both `environment.yml` (used for conda) and `setup.py` (used by pip, and in automatic CircleCI tests). -* For all PRs, make sure to update any existing config files, tutorials, and scripts to match your changes. -* For PRs that typical users will need to be aware of, make a matching PR to the [documentation](https://github.com/nyu-mll/jiant-site/edit/master/documentation/README.md). We will merge that documentation PR once the original PR is merged in and pushed out in a release. (Proposals for better ways to do this are welcome.) -* For PRs that add a new model or task, explain what types of sentence encoders are supported for that task. -* For PRs that could change performance across multiple tasks, run performance regression tests on at least one representative task from each “family” of tasks. +#### Setting up your local dev environment to run the validation steps applied to PRs by the build system: +``` +pip install -r requirements-dev.txt +pre-commit install +``` diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index c84a66380..000000000 --- a/Dockerfile +++ /dev/null @@ -1,64 +0,0 @@ -# Dockerfile for jiant repo. Currently intended to run in our GCP environment. -# -# To set up Docker for local use, follow the first part of the Kubernetes -# install instructions (gcp/kubernetes/README.md) to install Docker and -# nvidia-docker. -# -# For local usage, see demo.with_docker.sh -# -# To run on Kubernetes, see gcp/kubernetes/run_batch.sh -# -# Note that --remote_log currently doesn't work with containers, -# since the host name seen by main.py is the name of the container, not the -# name of the host GCE instance. - -# Use CUDA base image. -FROM nvidia/cuda:9.0-cudnn7-devel-ubuntu16.04 - -# Fix unicode issues in Python3 by setting default text file encoding. -ENV LANG C.UTF-8 - -# Update Ubuntu packages and install basic utils -RUN apt-get update -RUN apt-get install -y wget git bzip2 - -# Install Anaconda -RUN wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh \ - && bash Miniconda3-latest-Linux-x86_64.sh -b -p /opt/anaconda3 \ - && rm Miniconda3-latest-Linux-x86_64.sh - -# Set path to conda -ENV PATH /opt/anaconda3/bin:$PATH - -# Set up conda environment (slow - installs many packages) -COPY environment.yml . -RUN conda env create -f environment.yml - -# Workaround for 'conda activate' depending on shell features -# that don't necessarily work in Docker. -# This simulates the effect of 'conda activate' -# See https://github.com/ContinuumIO/docker-images/issues/89 -# If this breaks in a future version of conda, add -# RUN conda shell.posix activate jiant -# to see what conda activate jiant would do, and update the commands below -# accordingly. -ENV PATH /opt/anaconda3/envs/jiant/bin:$PATH -ENV CONDA_PREFIX "/opt/anaconda3/envs/jiant" -ENV CONDA_SHLVL "1" -ENV CONDA_DEFAULT_ENV "jiant" - -# Install SpaCy and NLTK models -RUN python -m spacy download en -RUN python -m nltk.downloader -d /usr/share/nltk_data \ - perluniprops nonbreaking_prefixes - -# Local AllenNLP cache, may be used for ELMo weights. -RUN mkdir -p /tmp/.allennlp && chmod a+w /tmp/.allennlp -ENV ALLENNLP_CACHE_ROOT "/tmp/.allennlp" - -# Create local mount points. -# Can override with --build-arg NFS_MOUNT=/path/to/nfs/volume -# when running 'docker build' -ARG NFS_MOUNT="/nfs/jiant" -RUN mkdir -p "$NFS_MOUNT" - diff --git a/LICENSE b/LICENSE index 787af08a1..805055111 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2019 New York University +Copyright (c) 2020 New York University Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index 9df1e2128..000000000 --- a/MANIFEST.in +++ /dev/null @@ -1 +0,0 @@ -recursive-include jiant/config/ *.conf diff --git a/README.md b/README.md index a74677b88..c6a28283a 100644 --- a/README.md +++ b/README.md @@ -1,63 +1,90 @@ -# `jiant` is an nlp toolkit - -[![CircleCI](https://circleci.com/gh/nyu-mll/jiant/tree/master.svg?style=svg)](https://circleci.com/gh/nyu-mll/jiant/tree/master) [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/python/black) - - -`jiant` is a software toolkit for natural language processing research, designed to facilitate work on multitask learning and transfer learning for sentence understanding tasks. - -A few things you might want to know about `jiant`: - -- `jiant` is configuration-driven. You can run an enormous variety of experiments by simply writing configuration files. Of course, if you need to add any major new features, you can also easily edit or extend the code. -- `jiant` contains implementations of strong baselines for the [GLUE](https://gluebenchmark.com) and [SuperGLUE](https://super.gluebenchmark.com/) benchmarks, and it's the recommended starting point for work on these benchmarks. -- `jiant` was developed at [the 2018 JSALT Workshop](https://www.clsp.jhu.edu/workshops/18-workshop/) by [the General-Purpose Sentence Representation Learning](https://jsalt18-sentence-repl.github.io/) team and is maintained by [the NYU Machine Learning for Language Lab](https://wp.nyu.edu/ml2/people/), with help from [many outside collaborators](https://github.com/nyu-mll/jiant/graphs/contributors) (especially Google AI Language's [Ian Tenney](https://ai.google/research/people/IanTenney)). -- `jiant` is built on [PyTorch](https://pytorch.org). It also uses many components from [AllenNLP](https://github.com/allenai/allennlp) and the HuggingFace Transformers [implementations](https://github.com/huggingface/transformers) for GPT, BERT and other transformer models. - -For a full system overview of `jiant` version 1.3.0, see https://arxiv.org/abs/2003.02249. - -## Getting Started - -To find the setup instructions for using jiant and to run a simple example demo experiment using data from GLUE, follow this [getting started tutorial](https://github.com/nyu-mll/jiant/tree/master/tutorials/setup_tutorial.md)! - - -## Contributing -Guidelines for contributing to `jiant` are available [here](CONTRIBUTING.md). - - -## Official Documentation +
+ +# `jiant` is an NLP toolkit +**The multitask and transfer learning toolkit for natural language processing research** + +[![Generic badge](https://img.shields.io/github/v/release/nyu-mll/jiant)](https://shields.io/) +[![codecov](https://codecov.io/gh/nyu-mll/jiant/branch/master/graph/badge.svg)](https://codecov.io/gh/nyu-mll/jiant) +[![CircleCI](https://circleci.com/gh/nyu-mll/jiant/tree/master.svg?style=shield)](https://circleci.com/gh/nyu-mll/jiant/tree/master) +[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) +[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT) + +
+ +**Why should I use `jiant`?** +- `jiant` supports [multitask learning](https://colab.research.google.com/github/nyu-mll/jiant/examples/notebooks/jiant_Multi_Task_Example.ipynb) +- `jiant` supports [transfer learning](https://colab.research.google.com/github/nyu-mll/jiant/examples/notebooks/jiant_STILTs_Example.ipynb) +- `jiant` supports [50+ natural language understanding tasks](./md_docs/tasks.md) +- `jiant` supports the following benchmarks: + - [GLUE](./guides/benchmarks/glue.md) + - [SuperGLUE](./guides/benchmarks/superglue.md) + - [XTREME](./guides/benchmarks/xtreme.md) +- `jiant` is a research library and users are encouraged to extend, change, and contribute to match their needs! + +**A few additional things you might want to know about `jiant`:** +- `jiant` is configuration file driven +- `jiant` is built with [PyTorch](https://pytorch.org) +- `jiant` integrates with [`datasets`](https://github.com/huggingface/datasets) to manage task data +- `jiant` integrates with [`transformers`](https://github.com/huggingface/transformers) to manage models and tokenizers. + + +### Quick Introduction +The following example fine tunes a RoBERTa model on the MRPC dataset. + +Python version: +```python +from jiant.proj.simple import runscript as run +import jiant.scripts.download_data.runscript as downloader + +# Download the Data +downloader.download_data([“mrpc”], "/content/data") + +# Set up the arguments for the Simple API +args = run.RunConfiguration( + run_name="simple", + exp_dir="/content/exp", + data_dir="/content/data", + model_type="roberta-base", + tasks="mrpc", + train_batch_size=16, + num_train_epochs=3 +) + +# Run! +run.run_simple(args) +``` -Our official documentation is here: https://jiant.info/documentation#/ +Bash version: +```bash +python jiant/scripts/download_data/runscript.py download --tasks mrpc --output_path /content/data +python jiant/proj/simple/runscript.py run --run_name=simple --exp_dir /content/data --data_dir /content/data --model_type roberta-base --tasks mrpc --train_batch_size 16 --num_train_epochs 3 +``` +Examples of more complex training workflows are found [here](./examples/README.md). -## Running -To run an experiment, make a config file similar to `jiant/config/demo.conf` with your model configuration. In addition, you can use the `--overrides` flag to override specific variables. For example: -```sh -python main.py --config_file jiant/config/demo.conf \ - --overrides "exp_name = my_exp, run_name = foobar, d_hid = 256" +### Installation +To install `jiant` as a user: ``` -will run the demo config, but output to `$JIANT_PROJECT_PREFIX/my_exp/foobar`. - To run the demo config, you will have to set environment variables. The best way to achieve that is to follow the instructions in [user_config_template.sh](user_config_template.sh) -* `$JIANT_PROJECT_PREFIX`: the where the outputs will be saved. -* `$JIANT_DATA_DIR`: location of the saved data. This is usually the location of the GLUE data in a simple default setup. -* `$WORD_EMBS_FILE`: location of any word embeddings you want to use (not necessary when using ELMo, GPT, or BERT). You can download GloVe (840B) [here](http://nlp.stanford.edu/data/glove.840B.300d.zip) or fastText (2M) [here](https://dl.fbaipublicfiles.com/fasttext/vectors-english/crawl-300d-2M.vec.zip). -To have `user_config.sh` run automatically, follow instructions in [scripts/export_from_bash.sh](export_from_bash.sh). - +pip install jiant +``` +To install `jiant` as a developer: +``` +git clone https://github.com/nyu-mll/jiant.git +cd jiant +pip install -e . +``` +To check `jiant` was correctly installed, run a [simple example](./examples/notebooks/simple_api_fine_tuning.ipynb). -## Suggested Citation -If you use `jiant` in academic work, please cite it directly: +### Contributing +The `jiant` project's contributing guidelines can be found [here](CONTRIBUTING.md). -``` -@misc{wang2019jiant, - author = {Alex Wang and Ian F. Tenney and Yada Pruksachatkun and Phil Yeres and Jason Phang and Haokun Liu and Phu Mon Htut and and Katherin Yu and Jan Hula and Patrick Xia and Raghu Pappagari and Shuning Jin and R. Thomas McCoy and Roma Patel and Yinghui Huang and Edouard Grave and Najoung Kim and Thibault F\'evry and Berlin Chen and Nikita Nangia and Anhad Mohananey and Katharina Kann and Shikha Bordia and Nicolas Patry and David Benton and Ellie Pavlick and Samuel R. Bowman}, - title = {\texttt{jiant} 1.3: A software toolkit for research on general-purpose text understanding models}, - howpublished = {\url{http://jiant.info/}}, - year = {2019} -} -``` +### Looking for `jiant v1.3.2`? +`jiant v1.3.2` has been moved to [jiant-v1-legacy](https://github.com/nyu-mll/jiant-v1-legacy) to support ongoing research with the library. `jiant v2.x.x` is more modular and scalable than `jiant v1.3.2` and has been designed to reflect the needs of the current NLP research community. We strongly recommended any new projects use `jiant v2.x.x`. -## Papers +#### Papers using `jiant v1.3.2` -`jiant` has been used in these four papers so far: +[`jiant`](https://github.com/nyu-mll/jiant-v1-legacy) has been used in these papers so far: - [Can You Tell Me How to Get Past Sesame Street? Sentence-Level Pretraining Beyond Language Modeling](https://arxiv.org/abs/1812.10860) (formerly "Looking for ELMo's Friends") - [What do you learn from context? Probing for sentence structure in contextualized word representations](https://openreview.net/forum?id=SJzSgnRcKX) ("edge probing") @@ -67,46 +94,33 @@ If you use `jiant` in academic work, please cite it directly: To exactly reproduce experiments from [the ELMo's Friends paper](https://arxiv.org/abs/1812.10860) use the [`jsalt-experiments`](https://github.com/jsalt18-sentence-repl/jiant/tree/jsalt-experiments) branch. That will contain a snapshot of the code as of early August, potentially with updated documentation. -For the [edge probing paper](https://openreview.net/forum?id=SJzSgnRcKX) and the [BERT layer paper](https://arxiv.org/abs/1905.05950), see the [probing/](probing/) directory. +For the [edge probing paper](https://openreview.net/forum?id=SJzSgnRcKX) and the [BERT layer paper](https://arxiv.org/abs/1905.05950), see the [probing/](https://github.com/nyu-mll/jiant-v1-legacy/tree/master/probing) directory. For the [function word probing paper](https://arxiv.org/abs/1904.11544), use [this branch](https://github.com/nyu-mll/jiant/tree/naacl_probingpaper) and refer to the instructions in the [scripts/fwords/](https://github.com/nyu-mll/jiant/tree/naacl_probingpaper/scripts/fwords) directory. For the [BERT NPI paper](https://arxiv.org/abs/1909.02597) follow the instructions in [scripts/bert_npi](https://github.com/nyu-mll/jiant/tree/blimp-and-npi/scripts/bert_npi) on the [`blimp-and-npi`](https://github.com/nyu-mll/jiant/tree/blimp-and-npi) branch. -## Getting Help - -Post an issue here on GitHub if you have any problems, and create a pull request if you make any improvements (substantial or cosmetic) to the code that you're willing to share. - - -## Releases - -Releases are identified using git tags and distributed via PyPI for pip installation. After passing CI tests and creating a new git tag for a release, it can be uploaded to PyPI by running: +### Citation -```bash -# create distribution -python setup.py sdist bdist_wheel +If you use `jiant ≥ v2.0.0` in academic work, please cite it directly: -# upload to PyPI -python -m twine upload dist/* +``` +@misc{phang2020jiant, + author = {Jason Phang and Phil Yeres and Jesse Swanson and Haokun Liu and Ian F. Tenney and Phu Mon Htut and Clara Vania and Alex Wang and Samuel R. Bowman}, + title = {\texttt{jiant} 2.0: A software toolkit for research on general-purpose text understanding models}, + howpublished = {\url{http://jiant.info/}}, + year = {2020} +} ``` -More details can be found in [setup.py](setup.py). - - -## License - -This package is released under the [MIT License](LICENSE.md). The material in the allennlp_mods directory is based on [AllenNLP](https://github.com/allenai/allennlp), which was originally released under the Apache 2.0 license. - +If you use `jiant ≤ v1.3.2` in academic work, please use the citation found [here](https://github.com/nyu-mll/jiant-v1-legacy). -## Acknowledgments +### Acknowledgments -- Part of the development of `jiant` took at the 2018 Frederick Jelinek Memorial Summer Workshop on Speech and Language Technologies, and was supported by Johns Hopkins University with unrestricted gifts from Amazon, Facebook, Google, Microsoft and Mitsubishi Electric Research Laboratories. - This work was made possible in part by a donation to NYU from Eric and Wendy Schmidt made by recommendation of the Schmidt Futures program, and by support from Intuit Inc. - We gratefully acknowledge the support of NVIDIA Corporation with the donation of a Titan V GPU used at NYU in this work. -- Developer Alex Wang is supported by the National Science Foundation Graduate Research Fellowship Program under Grant -No. DGE 1342536. Any opinions, findings, and conclusions or recommendations expressed in this -material are those of the author(s) and do not necessarily reflect the views of the National Science -Foundation. -- Developer Yada Pruksachatkun is supported by the Moore-Sloan Data Science Environment as part of the NYU Data Science Services initiative. -- Sam Bowman's work on `jiant` during Summer 2019 took place in his capacity as a visiting researcher at Google. +- Developer Jesse Swanson is supported by the Moore-Sloan Data Science Environment as part of the NYU Data Science Services initiative. + +### License +`jiant` is released under the [MIT License](https://github.com/jiant-dev/jiant/blob/master/LICENSE). \ No newline at end of file diff --git a/allennlp_mods b/allennlp_mods deleted file mode 120000 index cda86e3c5..000000000 --- a/allennlp_mods +++ /dev/null @@ -1 +0,0 @@ -jiant/allennlp_mods \ No newline at end of file diff --git a/assets/simple_api/task_config_templates.json b/assets/simple_api/task_config_templates.json new file mode 100644 index 000000000..5670bb8e1 --- /dev/null +++ b/assets/simple_api/task_config_templates.json @@ -0,0 +1,128 @@ +{ + "boolq": { + "task": "boolq", + "rel_paths": { + "train": "./train.jsonl", + "val": "./val.jsonl", + "test": "./test.jsonl" + }, + "name": "boolq" + }, + "ccg": { + "task": "ccg", + "rel_paths": { + "train": "./ccg.train", + "val": "./ccg.dev", + "test": "./ccg.test", + "tags_to_id": "./tags_to_id.json" + }, + "name": "ccg" + }, + "cola": { + "task": "cola", + "rel_paths": { + "train": "./train.jsonl", + "val": "./val.jsonl", + "test": "./test.jsonl" + }, + "name": "cola" + }, + "cosmosqa": { + "task": "cosmosqa", + "rel_paths": { + "train": "./train.csv", + "val": "./valid.csv", + "test": "./test_no_label.csv" + }, + "name": "cosmosqa" + }, + "hellaswag": { + "task": "hellaswag", + "rel_paths": { + "train": "./hellaswag_train.jsonl", + "val": "./hellaswag_val.jsonl", + "test": "./hellaswag_test.jsonl" + }, + "name": "hellaswag" + }, + "mnli": { + "task": "mnli", + "rel_paths": { + "train": "./train.jsonl", + "val": "./val.jsonl", + "test": "./test.jsonl" + }, + "name": "mnli" + }, + "mrpc": { + "task": "mrpc", + "rel_paths": { + "train": "./train.jsonl", + "val": "./val.jsonl", + "test": "./test.jsonl" + }, + "name": "mrpc" + }, + "qnli": { + "task": "qnli", + "rel_paths": { + "train": "./train.jsonl", + "val": "./val.jsonl", + "test": "./test.jsonl" + }, + "name": "qnli" + }, + "qqp": { + "task": "qqp", + "rel_paths": { + "train": "./train.jsonl", + "val": "./val.jsonl", + "test": "./test.jsonl" + }, + "name": "qqp" + }, + "rte": { + "task": "rte", + "rel_paths": { + "train": "./train.jsonl", + "val": "./val.jsonl", + "test": "./test.jsonl" + }, + "name": "rte" + }, + "squad_v1": { + "task": "squad", + "rel_paths": { + "train": "./train-v1.1.json", + "val": "./dev-v1.1.json" + }, + "name": "squad_v1" + }, + "stsb": { + "task": "stsb", + "rel_paths": { + "train": "./train.jsonl", + "val": "./val.jsonl", + "test": "./test.jsonl" + }, + "name": "stsb" + }, + "wic": { + "task": "wic", + "rel_paths": { + "train": "./train.jsonl", + "val": "./val.jsonl", + "test": "./test.jsonl" + }, + "name": "wic" + }, + "wnli": { + "task": "wnli", + "rel_paths": { + "train": "./train.jsonl", + "val": "./val.jsonl", + "test": "./test.jsonl" + }, + "name": "wnli" + } +} diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 000000000..c9cf44628 --- /dev/null +++ b/codecov.yml @@ -0,0 +1,4 @@ +coverage: + status: + project: false + patch: false diff --git a/cola_inference.py b/cola_inference.py deleted file mode 100644 index 7c978ae21..000000000 --- a/cola_inference.py +++ /dev/null @@ -1,348 +0,0 @@ -""" -Run a model inference via a REPL (read-eval-print loop), or by processing an input corpus file. - -To run as REPL (default): - - python cola_inference.py \ - --config_file PATH_TO_CONFIG_FILE \ - --model_file_path PATH_TO_FILE_PATH - - -To process a corpus: - - python cola_inference.py \ - --config_file PATH_TO_CONFIG_FILE \ - --model_file_path PATH_TO_FILE_PATH \ - --inference_mode corpus \ - --input_path PATH_TO_INPUT_CORPUS \ - --output_path PATH_TO_WRITE_OUTPUT - -To process+evaluate (e.g.) the CoLA dev set: - - python cola_inference.py \ - --config_file PATH_TO_CONFIG_FILE \ - --model_file_path PATH_TO_FILE_PATH \ - --inference_mode corpus \ - --input_path PATH_TO_INPUT_CORPUS \ - --input_format dev \ - --output_path PATH_TO_WRITE_OUTPUT - -(Ensure that the repository is in your PYTHONPATH when running this script.) - -""" -# pylint: disable=no-member -import argparse -import json -import logging as log -import os -import sys - -import numpy as np -import pandas as pd -import torch -from allennlp.data import Instance, Vocabulary -from allennlp.data.dataset import Batch -from allennlp.nn.util import move_to_device -from tqdm import tqdm - -from jiant.models import build_model -from jiant.preprocess import build_indexers, build_tasks, ModelPreprocessingInterface -from jiant.tasks.tasks import tokenize_and_truncate, sentence_to_text_field -from jiant.utils import config -from jiant.utils.data_loaders import load_tsv -from jiant.utils.utils import load_model_state, select_pool_type -from jiant.utils.options import parse_cuda_list_arg -from jiant.utils.tokenizers import select_tokenizer -from jiant.__main__ import check_arg_name - -log.basicConfig(format="%(asctime)s: %(message)s", datefmt="%m/%d %I:%M:%S %p", level=log.INFO) - - -def handle_arguments(cl_arguments): - parser = argparse.ArgumentParser(description="") - - # Configuration files - parser.add_argument( - "--config_file", - "-c", - type=str, - nargs="+", - help="Config file(s) (.conf) for model parameters.", - ) - parser.add_argument( - "--overrides", - "-o", - type=str, - default=None, - help="Parameter overrides, as valid HOCON string.", - ) - - # Inference arguments - parser.add_argument( - "--model_file_path", type=str, required=True, help="Path to saved model (.th)." - ) - parser.add_argument( - "--inference_mode", - type=str, - default="repl", - help="Run as REPL, or process a corpus file." " [repl, corpus]", - ) - parser.add_argument( - "--input_path", - type=str, - default=None, - help="Input path for running inference." - " One input per line." - " Only in eval_mode='corpus'", - ) - parser.add_argument( - "--input_format", - type=str, - default="text", - help="Format of input (text | train | dev | test)", - ) - parser.add_argument( - "--output_path", - type=str, - default=None, - help="Output path for running inference." " Only in eval_mode='corpus'", - ) - parser.add_argument( - "--eval_output_path", - type=str, - default=None, - help="Output path for metrics from evaluation." " Only in eval_mode='corpus'", - ) - - return parser.parse_args(cl_arguments) - - -def main(cl_arguments): - """ Run REPL for a CoLA model """ - - # Arguments handling # - cl_args = handle_arguments(cl_arguments) - args = config.params_from_file(cl_args.config_file, cl_args.overrides) - check_arg_name(args) - - assert args.target_tasks == "cola", "Currently only supporting CoLA. ({})".format( - args.target_tasks - ) - - if args.cuda >= 0: - try: - if not torch.cuda.is_available(): - raise EnvironmentError("CUDA is not available, or not detected" " by PyTorch.") - log.info("Using GPU %d", args.cuda) - torch.cuda.set_device(args.cuda) - except Exception: - log.warning( - "GPU access failed. You might be using a CPU-only" - " installation of PyTorch. Falling back to CPU." - ) - args.cuda = -1 - - if args.tokenizer == "auto": - args.tokenizer = select_tokenizer(args) - if args.pool_type == "auto": - args.pool_type = select_pool_type(args) - - # Prepare data # - cuda_device = parse_cuda_list_arg(args.cuda) - _, target_tasks, vocab, word_embs = build_tasks(args, cuda_device) - tasks = sorted(set(target_tasks), key=lambda x: x.name) - - # Build or load model # - model = build_model(args, vocab, word_embs, tasks, cuda_device) - log.info("Loading existing model from %s...", cl_args.model_file_path) - load_model_state(model, cl_args.model_file_path, args.cuda, [], strict=False) - - # Inference Setup # - model.eval() - vocab = Vocabulary.from_files(os.path.join(args.exp_dir, "vocab")) - indexers = build_indexers(args) - task = take_one(tasks) - model_preprocessing_interface = ModelPreprocessingInterface(args) - - # Run Inference # - if cl_args.inference_mode == "repl": - assert cl_args.input_path is None - assert cl_args.output_path is None - print("Running REPL for task: {}".format(task.name)) - run_repl(model, model_preprocessing_interface, vocab, indexers, task, args) - elif cl_args.inference_mode == "corpus": - run_corpus_inference( - model, - model_preprocessing_interface, - vocab, - indexers, - task, - args, - cl_args.input_path, - cl_args.input_format, - cl_args.output_path, - cl_args.eval_output_path, - ) - else: - raise KeyError(cl_args.inference_mode) - - -def run_repl(model, model_preprocessing_interface, vocab, indexers, task, args): - """ Run REPL """ - print("Input CTRL-C or enter 'QUIT' to terminate.") - while True: - try: - print() - input_string = input(" INPUT: ") - if input_string == "QUIT": - break - - tokens = tokenize_and_truncate( - tokenizer_name=task.tokenizer_name, sent=input_string, max_seq_len=args.max_seq_len - ) - print("TOKENS:", " ".join("[{}]".format(tok) for tok in tokens)) - field = sentence_to_text_field( - model_preprocessing_interface.boundary_token_fn(tokens), indexers - ) - field.index(vocab) - batch = Batch([Instance({"input1": field})]).as_tensor_dict() - batch = move_to_device(batch, args.cuda) - with torch.no_grad(): - out = model.forward(task, batch, predict=True) - assert out["logits"].shape[1] == 2 - - s = " PRED: " - s += "TRUE " if out["preds"][0].item() else "FALSE" - s += " ({:.1f}%, logits: {:.3f} vs {:.3f})".format( - torch.softmax(out["logits"][0], dim=0)[1].item() * 100, - out["logits"][0][0].item(), - out["logits"][0][1].item(), - ) - print(s) - except KeyboardInterrupt: - print("\nTerminating.") - break - - -def run_corpus_inference( - model, - model_preprocessing_interface, - vocab, - indexers, - task, - args, - input_path, - input_format, - output_path, - eval_output_path, -): - """ Run inference on corpus """ - tokens, labels = load_cola_data(input_path, task, input_format, args.max_seq_len) - logit_batches = [] - for tokens_batch in tqdm(list(batchify(tokens, args.batch_size))): - batch, _ = prepare_batch(model_preprocessing_interface, tokens_batch, vocab, indexers, args) - with torch.no_grad(): - out = model.forward(task, batch, predict=True) - logit_batches.append(out["logits"].cpu().numpy()) - - logits = np.concatenate(logit_batches, axis=0) - probs = torch.softmax(torch.tensor(logits), dim=1).numpy() - preds = np.argmax(probs, axis=1) - - data_out = np.concatenate([logits, probs], axis=1) - - # Future-proofing - assert task.name == "cola" - num_classes = logits.shape[1] - columns = [f"logit_{i}" for i in range(num_classes)] + [f"prob_{i}" for i in range(num_classes)] - - df = pd.DataFrame(data_out, columns=columns) - df["pred"] = preds - - df.to_csv(output_path, index=False) - - if labels is not None: - metrics = get_cola_metrics(logits, preds, labels, task) - metrics_str = json.dumps(metrics, indent=2) - print(metrics_str) - if eval_output_path is not None: - with open(eval_output_path, "w") as f: - f.write(metrics_str) - else: - assert eval_output_path is None - - -def batchify(ls, batch_size): - """ Partition a list into batches of batch_size """ - i = 0 - while i < len(ls): - yield ls[i : i + batch_size] - i += batch_size - - -def prepare_batch(model_preprocessing_interface, tokens_batch, vocab, indexers, args): - """ Do preprocessing for batch """ - instance_ls = [] - token_ls = [] - for tokens in tokens_batch: - field = sentence_to_text_field( - model_preprocessing_interface.boundary_token_fn(tokens), indexers - ) - field.index(vocab) - instance_ls.append(Instance({"input1": field})) - token_ls.append(tokens) - batch = Batch(instance_ls).as_tensor_dict() - batch = move_to_device(batch, args.cuda) - return batch, token_ls - - -def take_one(ls): - """ Extract singleton from list """ - assert len(ls) == 1 - return ls[0] - - -def load_cola_data(input_path, task, input_format, max_seq_len): - if input_format == "text": - with open(input_path, "r") as f_in: - sentences = f_in.readlines() - tokens = [ - tokenize_and_truncate( - tokenizer_name=task.tokenizer_name, sent=sentence, max_seq_len=max_seq_len - ) - for sentence in sentences - ] - labels = None - elif input_format == "train" or input_format == "dev": - data = load_tsv( - task.tokenizer_name, input_path, max_seq_len, s1_idx=3, s2_idx=None, label_idx=1 - ) - tokens, labels = data[0], data[2] - elif input_format == "test": - data = load_tsv( - task.tokenizer_name, - input_path, - max_seq_len, - s1_idx=1, - s2_idx=None, - has_labels=False, - return_indices=True, - skip_rows=1, - ) - tokens, labels = data[0], None - else: - raise KeyError(input_format) - return tokens, labels - - -def get_cola_metrics(logits, preds, labels, task): - labels_tensor = torch.tensor(np.array(labels)) - logits_tensor = torch.tensor(logits) - preds_tensor = torch.tensor(preds) - task.scorer2(logits_tensor, labels_tensor) - task.scorer1(labels_tensor, preds_tensor) - return task.get_metrics(reset=True) - - -if __name__ == "__main__": - main(sys.argv[1:]) diff --git a/conftest.py b/conftest.py new file mode 100644 index 000000000..094ad4576 --- /dev/null +++ b/conftest.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- +""" +Skipping slow tests according to command line: https://docs.pytest.org/en/latest/example/simple.html +""" +import pytest + + +def pytest_addoption(parser): + parser.addoption("--runslow", action="store_true", default=False, help="run slow tests") + parser.addoption("--rungpu", action="store_true", default=False, help="run gpu tests") + + +def pytest_configure(config): + config.addinivalue_line("markers", "slow: mark test as slow to run") + config.addinivalue_line("markers", "gpu: mark test as gpu required to run") + + +def pytest_collection_modifyitems(config, items): + if not config.getoption("--runslow"): + skip_slow = pytest.mark.skip(reason="need --runslow option to run") + for item in items: + if "slow" in item.keywords: + item.add_marker(skip_slow) + if not config.getoption("--rungpu"): + skip_gpu = pytest.mark.skip(reason="need --rungpu option to run") + for item in items: + if "gpu" in item.keywords: + item.add_marker(skip_gpu) diff --git a/environment.yml b/environment.yml deleted file mode 100644 index 3c23a0df6..000000000 --- a/environment.yml +++ /dev/null @@ -1,47 +0,0 @@ -name: jiant -channels: - - pytorch -dependencies: - - python=3.6 - - pytorch=1.1.0 - - torchvision=0.2.1 - - numpy=1.15.0 - - scikit-learn=0.19.1 - - pandas=0.23.0 - # bokeh for plotting - - bokeh=1.2.0 - - ipykernel=5.1.1 - - pytz=2017.3 - - jsondiff - - pip - - pip: - - allennlp==0.8.4 - - ipdb - - tensorboard - - tensorboardX==1.2 - - sendgrid==5.4.1 - - pyhocon==0.3.35 - - nose2 - - pre-commit==1.15.2 - - # for span alignment / retokenization - - python-Levenshtein==0.12.0 - - # for --remote_log functionality - - google-cloud-logging==1.11.0 - - # for some tokenizers in huggingface transformers - - spacy==2.1 - - ftfy - - # for tokenization - - nltk==3.4.5 - - sacremoses - - # Warning: jiant currently depends on *both* pytorch_pretrained_bert > 0.6 _and_ - # transformers > 2.6.0. These are the same package, though the name changed between - # these two versions. AllenNLP requires 0.6 to support the BertAdam optimizer, and jiant - # directly requires 1.0 to support XLNet and WWM-BERT. - # This AllenNLP issue is relevant: https://github.com/allenai/allennlp/issues/3067 - - transformers==2.6.0 - - tokenizers==0.5.2 diff --git a/examples/README.md b/examples/README.md new file mode 100644 index 000000000..574992f5d --- /dev/null +++ b/examples/README.md @@ -0,0 +1,19 @@ +# Examples + +## Example Notebooks + +* **Fine-tuning on a single task with the simple API** [[Notebook](./notebooks/simple_api_fine_tuning.ipynb)] [[Colab](https://colab.research.google.com/github/jiant-dev/jiant/blob/master/examples/notebooks/simple_api_fine_tuning.ipynb)] +* **Fine-tuning on a single task with the main API** [[Notebook](./notebooks/jiant_Basic_Example.ipynb)] [[Colab](https://colab.research.google.com/github/jiant-dev/jiant/blob/master/examples/notebooks/jiant_Basic_Example.ipynb)] +* **Multi-task Training** [[Notebook](./notebooks/jiant_Multi_Task_Example.ipynb)] [[Colab](https://colab.research.google.com/github/jiant-dev/jiant/blob/master/examples/notebooks/jiant_Multi_Task_Example.ipynb)] + * Fine-tuning on multiple tasks simultaneously +* **STILTs Training** [[Notebook](./notebooks/jiant_STILTs_Example.ipynb)] [[Colab](https://colab.research.google.com/github/jiant-dev/jiant/blob/master/examples/notebooks/jiant_STILTs_Example.ipynb)] + * Fine-tuning on multiple tasks sequentially +* **Zero-shot transfer to XNLI** [[Notebook](./notebooks/jiant_XNLI_Example.ipynb)] [[Colab](https://colab.research.google.com/github/jiant-dev/jiant/blob/master/examples/notebooks/jiant_XNLI_Example.ipynb)] + * Fine-tuning on MNLI for zero-shot transfer to XNLI +* **MNLI-mismatched/GLUE Diagnostic** [[Notebook](./notebooks/jiant_MNLI_Diagnostic_Example.ipynb)] [[Colab](https://colab.research.google.com/github/jiant-dev/jiant/blob/master/examples/notebooks/jiant_MNLI_Diagnostic_Example.ipynb)] + * Fine-tuning on MNLI for MNLI-mismatched and GLUE Diagnostic set + + +## Other Examples +* **Adding Tasks** + * Adding a single-sentence classification task [[Guide](./guides/adding_tasks.md)] diff --git a/examples/notebooks/jiant_Basic_Example.ipynb b/examples/notebooks/jiant_Basic_Example.ipynb new file mode 100644 index 000000000..c0d5cd566 --- /dev/null +++ b/examples/notebooks/jiant_Basic_Example.ipynb @@ -0,0 +1,381 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "O9I9rz0pTamX" + }, + "source": [ + "# Basic RoBERTa Fine-tuning Example" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "EiowR0WNTd1C" + }, + "source": [ + "In this notebook, we will:\n", + "\n", + "* Train a RoBERTa base model on MRPC and evaluate its performance" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "rXbD_U1_VDnw" + }, + "source": [ + "## Setup" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "tC9teoazUnW8" + }, + "source": [ + "#### Install dependencies\n", + "\n", + "First, we will install libraries we need for this code." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "8aU3Z9szuMU9" + }, + "outputs": [], + "source": [ + "%%capture\n", + "!git clone https://github.com/jiant-dev/jiant.git\n", + "!cd jiant\n", + "!git checkout d26c213c742d36f8909f3a910694c8a90da416f1\n", + "!cd .." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "hMUKEH2YvFPv" + }, + "outputs": [], + "source": [ + "%%capture\n", + "# This Colab notebook already has its CUDA-runtime compatible versions of torch and torchvision installed\n", + "!pip install -r jiant/requirements-no-torch.txt\n", + "# Install pyarrow for nlp\n", + "!pip install pyarrow==0.16.0" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "KGJcCmRzU1Qb" + }, + "source": [ + "#### Download data\n", + "\n", + "Next, we will download task data. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "jKCz8VksvFlN" + }, + "outputs": [], + "source": [ + "%%capture\n", + "# Download MRPC data\n", + "!PYTHONPATH=/content/jiant python jiant/jiant/scripts/download_data/runscript.py \\\n", + " download \\\n", + " --tasks mrpc \\\n", + " --output_path=/content/tasks/" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "rQKSAhYzVIlv" + }, + "source": [ + "## `jiant` Pipeline" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "v88oXqmBvFuK" + }, + "outputs": [], + "source": [ + "import sys\n", + "sys.path.insert(0, \"/content/jiant\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "ibmMT7CXv1_P" + }, + "outputs": [], + "source": [ + "import jiant.proj.main.tokenize_and_cache as tokenize_and_cache\n", + "import jiant.proj.main.export_model as export_model\n", + "import jiant.proj.main.scripts.configurator as configurator\n", + "import jiant.proj.main.runscript as main_runscript\n", + "import jiant.shared.caching as caching\n", + "import jiant.utils.python.io as py_io\n", + "import jiant.utils.display as display\n", + "import os" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "HPZHyLOlVp07" + }, + "source": [ + "#### Download model\n", + "\n", + "Next, we will download a `roberta-base` model. This also includes the tokenizer." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "K06qUGjkKWa7" + }, + "outputs": [], + "source": [ + "export_model.lookup_and_export_model(\n", + " model_type=\"roberta-base\",\n", + " output_base_path=\"./models/roberta-base\",\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "dV-T-8r1V0wf" + }, + "source": [ + "#### Tokenize and cache\n", + "\n", + "With the model and data ready, we can now tokenize and cache the inputs features for our task. This converts the input examples to tokenized features ready to be consumed by the model, and saved them to disk in chunks." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "22bNWQajO4zm" + }, + "outputs": [], + "source": [ + "# Tokenize and cache each task\n", + "task_name = \"mrpc\"\n", + "\n", + "tokenize_and_cache.main(tokenize_and_cache.RunConfiguration(\n", + " task_config_path=f\"./tasks/configs/{task_name}_config.json\",\n", + " model_type=\"roberta-base\",\n", + " model_tokenizer_path=\"./models/roberta-base/tokenizer\",\n", + " output_dir=f\"./cache/{task_name}\",\n", + " phases=[\"train\", \"val\"],\n", + "))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "JJ-mWSQQWJsw" + }, + "source": [ + "We can inspect the first examples of the first chunk of each task." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "iLk_X0KypUyr" + }, + "outputs": [], + "source": [ + "row = caching.ChunkedFilesDataCache(\"./cache/mrpc/train\").load_chunk(0)[0][\"data_row\"]\n", + "print(row.input_ids)\n", + "print(row.tokens)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "3MBuH19IWOr0" + }, + "source": [ + "#### Writing a run config\n", + "\n", + "Here we are going to write what we call a `jiant_task_container_config`. This configuration file basically defines a lot of the subtleties of our training pipeline, such as what tasks we will train on, do evaluation on, batch size for each task. The new version of `jiant` leans heavily toward explicitly specifying everything, for the purpose of inspectability and leaving minimal surprises for the user, even as the cost of being more verbose.\n", + "\n", + "We use a helper \"Configurator\" to write out a `jiant_task_container_config`, since most of our setup is pretty standard. \n", + "\n", + "**Depending on what GPU your Colab session is assigned to, you may need to lower the train batch size.**" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "pQYtl7xTKsiP" + }, + "outputs": [], + "source": [ + "jiant_run_config = configurator.SimpleAPIMultiTaskConfigurator(\n", + " task_config_base_path=\"./tasks/configs\",\n", + " task_cache_base_path=\"./cache\",\n", + " train_task_name_list=[\"mrpc\"],\n", + " val_task_name_list=[\"mrpc\"],\n", + " train_batch_size=8,\n", + " eval_batch_size=16,\n", + " epochs=3,\n", + " num_gpus=1,\n", + ").create_config()\n", + "os.makedirs(\"./run_configs/\", exist_ok=True)\n", + "py_io.write_json(jiant_run_config, \"./run_configs/mrpc_run_config.json\")\n", + "display.show_json(jiant_run_config)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "-UF501yoXHBi" + }, + "source": [ + "To briefly go over the major components of the `jiant_task_container_config`:\n", + "\n", + "* `task_config_path_dict`: The paths to the task config files we wrote above.\n", + "* `task_cache_config_dict`: The paths to the task features caches we generated above.\n", + "* `sampler_config`: Determines how to sample from different tasks during training.\n", + "* `global_train_config`: The number of total steps and warmup steps during training.\n", + "* `task_specific_configs_dict`: Task-specific arguments for each task, such as training batch size and gradient accumulation steps.\n", + "* `taskmodels_config`: Task-model specific arguments for each task-model, including what tasks use which model.\n", + "* `metric_aggregator_config`: Determines how to weight/aggregate the metrics across multiple tasks." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "BBKkvXzdYPqZ" + }, + "source": [ + "#### Start training\n", + "\n", + "Finally, we can start our training run. \n", + "\n", + "Before starting training, the script also prints out the list of parameters in our model." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "JdwWPgjQWx6I" + }, + "outputs": [], + "source": [ + "run_args = main_runscript.RunConfiguration(\n", + " jiant_task_container_config_path=\"./run_configs/mrpc_run_config.json\",\n", + " output_dir=\"./runs/mrpc\",\n", + " model_type=\"roberta-base\",\n", + " model_path=\"./models/roberta-base/model/roberta-base.p\",\n", + " model_config_path=\"./models/roberta-base/model/roberta-base.json\",\n", + " model_tokenizer_path=\"./models/roberta-base/tokenizer\",\n", + " learning_rate=1e-5,\n", + " eval_every_steps=500,\n", + " do_train=True,\n", + " do_val=True,\n", + " do_save=True,\n", + " force_overwrite=True,\n", + ")\n", + "main_runscript.run_loop(run_args)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "4SXcuHFIYp6Y" + }, + "source": [ + "At the end, you should see the evaluation scores for MRPC." + ] + } + ], + "metadata": { + "accelerator": "GPU", + "colab": { + "collapsed_sections": [], + "name": "jiant STILTs Example", + "provenance": [], + "toc_visible": true + }, + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.2" + } + }, + "nbformat": 4, + "nbformat_minor": 1 +} diff --git a/examples/notebooks/jiant_MNLI_Diagnostic_Example.ipynb b/examples/notebooks/jiant_MNLI_Diagnostic_Example.ipynb new file mode 100644 index 000000000..ff3587f37 --- /dev/null +++ b/examples/notebooks/jiant_MNLI_Diagnostic_Example.ipynb @@ -0,0 +1,400 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "O9I9rz0pTamX" + }, + "source": [ + "# MNLI Diagnostic Example" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "rXbD_U1_VDnw" + }, + "source": [ + "## Setup" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "tC9teoazUnW8" + }, + "source": [ + "#### Install dependencies" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "8aU3Z9szuMU9" + }, + "outputs": [], + "source": [ + "%%capture\n", + "!git clone https://github.com/jiant-dev/jiant.git\n", + "!cd jiant\n", + "!git checkout d26c213c742d36f8909f3a910694c8a90da416f1\n", + "!cd .." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "hMUKEH2YvFPv" + }, + "outputs": [], + "source": [ + "%%capture\n", + "# This Colab notebook already has its CUDA-runtime compatible versions of torch and torchvision installed\n", + "!pip install -r jiant/requirements-no-torch.txt\n", + "# Install pyarrow for nlp\n", + "!pip install pyarrow==0.16.0" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "KGJcCmRzU1Qb" + }, + "source": [ + "#### Download data" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "jKCz8VksvFlN" + }, + "outputs": [], + "source": [ + "%%capture\n", + "# Download/preprocess MNLI and Dognostic data\n", + "!PYTHONPATH=/content/jiant python jiant/jiant/scripts/download_data/runscript.py \\\n", + " download \\\n", + " --tasks mnli mnli_mismatched glue_diagnostics \\\n", + " --output_path=/content/tasks/" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "rQKSAhYzVIlv" + }, + "source": [ + "## `jiant` Pipeline" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "v88oXqmBvFuK" + }, + "outputs": [], + "source": [ + "import sys\n", + "sys.path.insert(0, \"/content/jiant\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "ibmMT7CXv1_P" + }, + "outputs": [], + "source": [ + "import jiant.proj.main.tokenize_and_cache as tokenize_and_cache\n", + "import jiant.proj.main.export_model as export_model\n", + "import jiant.proj.main.scripts.configurator as configurator\n", + "import jiant.proj.main.runscript as main_runscript\n", + "import jiant.shared.caching as caching\n", + "import jiant.utils.python.io as py_io\n", + "import jiant.utils.display as display\n", + "import os\n", + "import torch" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "HPZHyLOlVp07" + }, + "source": [ + "#### Download model" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "K06qUGjkKWa7" + }, + "outputs": [], + "source": [ + "export_model.lookup_and_export_model(\n", + " model_type=\"roberta-base\",\n", + " output_base_path=\"./models/roberta-base\",\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "dV-T-8r1V0wf" + }, + "source": [ + "#### Tokenize and cache\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "22bNWQajO4zm" + }, + "outputs": [], + "source": [ + "# Tokenize and cache each task\n", + "tokenize_and_cache.main(tokenize_and_cache.RunConfiguration(\n", + " task_config_path=f\"./tasks/configs/mnli_config.json\",\n", + " model_type=\"roberta-base\",\n", + " model_tokenizer_path=\"./models/roberta-base/tokenizer\",\n", + " output_dir=f\"./cache/mnli\",\n", + " phases=[\"train\", \"val\"],\n", + "))\n", + "\n", + "tokenize_and_cache.main(tokenize_and_cache.RunConfiguration(\n", + " task_config_path=f\"./tasks/configs/mnli_mismatched_config.json\",\n", + " model_type=\"roberta-base\",\n", + " model_tokenizer_path=\"./models/roberta-base/tokenizer\",\n", + " output_dir=f\"./cache/mnli_mismatched\",\n", + " phases=[\"val\"],\n", + "))\n", + "\n", + "tokenize_and_cache.main(tokenize_and_cache.RunConfiguration(\n", + " task_config_path=f\"./tasks/configs/glue_diagnostics_config.json\",\n", + " model_type=\"roberta-base\",\n", + " model_tokenizer_path=\"./models/roberta-base/tokenizer\",\n", + " output_dir=f\"./cache/glue_diagnostics\",\n", + " phases=[\"test\"],\n", + "))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "iLk_X0KypUyr" + }, + "outputs": [], + "source": [ + "row = caching.ChunkedFilesDataCache(\"./cache/mnli/train\").load_chunk(0)[0][\"data_row\"]\n", + "print(row.input_ids)\n", + "print(row.tokens)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "2n00e6Xrp1bI" + }, + "outputs": [], + "source": [ + "row = caching.ChunkedFilesDataCache(\"./cache/mnli_mismatched/val\").load_chunk(0)[0][\"data_row\"]\n", + "print(row.input_ids)\n", + "print(row.tokens)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "cjwnG_xXCelU" + }, + "outputs": [], + "source": [ + "row = caching.ChunkedFilesDataCache(\"./cache/glue_diagnostics/test\").load_chunk(0)[0][\"data_row\"]\n", + "print(row.input_ids)\n", + "print(row.tokens)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "3MBuH19IWOr0" + }, + "source": [ + "#### Writing a run config" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "pQYtl7xTKsiP" + }, + "outputs": [], + "source": [ + "jiant_run_config = configurator.SimpleAPIMultiTaskConfigurator(\n", + " task_config_base_path=\"./tasks/configs\",\n", + " task_cache_base_path=\"./cache\",\n", + " train_task_name_list=[\"mnli\"],\n", + " val_task_name_list=[\"mnli\", \"mnli_mismatched\"],\n", + " test_task_name_list=[\"glue_diagnostics\"],\n", + " train_batch_size=8,\n", + " eval_batch_size=16,\n", + " epochs=0.1,\n", + " num_gpus=1,\n", + ").create_config()\n", + "display.show_json(jiant_run_config)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "usn2oQo8ILwi" + }, + "source": [ + "Configure all three tasks to use an `mnli` head." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "624iqo12Gs7D" + }, + "outputs": [], + "source": [ + "jiant_run_config[\"taskmodels_config\"][\"task_to_taskmodel_map\"] = {\n", + " \"mnli\": \"mnli\",\n", + " \"mnli_mismatched\": \"mnli\",\n", + " \"glue_diagnostics\": \"glue_diagnostics\",\n", + "}\n", + "os.makedirs(\"./run_configs/\", exist_ok=True)\n", + "py_io.write_json(jiant_run_config, \"./run_configs/jiant_run_config.json\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "BBKkvXzdYPqZ" + }, + "source": [ + "#### Start training" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "JdwWPgjQWx6I" + }, + "outputs": [], + "source": [ + "run_args = main_runscript.RunConfiguration(\n", + " jiant_task_container_config_path=\"./run_configs/jiant_run_config.json\",\n", + " output_dir=\"./runs/run1\",\n", + " model_type=\"roberta-base\",\n", + " model_path=\"./models/roberta-base/model/roberta-base.p\",\n", + " model_config_path=\"./models/roberta-base/model/roberta-base.json\",\n", + " model_tokenizer_path=\"./models/roberta-base/tokenizer\",\n", + " learning_rate=1e-5,\n", + " eval_every_steps=500,\n", + " do_train=True,\n", + " do_val=True,\n", + " do_save=True,\n", + " write_test_preds=True,\n", + " force_overwrite=True,\n", + ")\n", + "main_runscript.run_loop(run_args)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "jOxAmtQmHu9E" + }, + "outputs": [], + "source": [ + "test_preds = torch.load(\"./runs/run1/test_preds.p\")\n", + "test_preds[\"glue_diagnostics\"]" + ] + } + ], + "metadata": { + "accelerator": "GPU", + "colab": { + "collapsed_sections": [], + "name": "jiant MNLI Diagnostic Example", + "provenance": [] + }, + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.2" + } + }, + "nbformat": 4, + "nbformat_minor": 1 +} diff --git a/examples/notebooks/jiant_Multi_Task_Example.ipynb b/examples/notebooks/jiant_Multi_Task_Example.ipynb new file mode 100644 index 000000000..d4ad1dc1d --- /dev/null +++ b/examples/notebooks/jiant_Multi_Task_Example.ipynb @@ -0,0 +1,414 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "O9I9rz0pTamX" + }, + "source": [ + "# Multi-Task Example" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "EiowR0WNTd1C" + }, + "source": [ + "In this notebook, we are going to fine-tune a multi-task model. Multi-task training is useful in many situations, and is a first-class feature in `jiant`.\n", + "\n", + "--- \n", + "\n", + "In this notebook, we will:\n", + "\n", + "* Train a RoBERTa base model on RTE, STS-B, and CommonsenseQA simultaneously" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "rXbD_U1_VDnw" + }, + "source": [ + "## Setup" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "tC9teoazUnW8" + }, + "source": [ + "#### Install dependencies\n", + "\n", + "First, we will install libraries we need for this code." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "8aU3Z9szuMU9" + }, + "outputs": [], + "source": [ + "%%capture\n", + "!git clone https://github.com/jiant-dev/jiant.git\n", + "!cd jiant\n", + "!git checkout d26c213c742d36f8909f3a910694c8a90da416f1\n", + "!cd .." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "hMUKEH2YvFPv" + }, + "outputs": [], + "source": [ + "%%capture\n", + "# This Colab notebook already has its CUDA-runtime compatible versions of torch and torchvision installed\n", + "!pip install -r jiant/requirements-no-torch.txt\n", + "# Install pyarrow for nlp\n", + "!pip install pyarrow==0.16.0" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "KGJcCmRzU1Qb" + }, + "source": [ + "#### Download data\n", + "\n", + "Next, we will download RTE, STS-B and CommonsenseQA data." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "NKfLVgxS-jsW" + }, + "outputs": [], + "source": [ + "%%capture\n", + "# Download RTE, STS-B and CommonsenseQA data\n", + "!PYTHONPATH=/content/jiant python jiant/jiant/scripts/download_data/runscript.py \\\n", + " download \\\n", + " --tasks rte stsb commonsenseqa \\\n", + " --output_path=/content/tasks/" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "rQKSAhYzVIlv" + }, + "source": [ + "## `jiant` Pipeline" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "v88oXqmBvFuK" + }, + "outputs": [], + "source": [ + "import sys\n", + "sys.path.insert(0, \"/content/jiant\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "ibmMT7CXv1_P" + }, + "outputs": [], + "source": [ + "import jiant.proj.main.tokenize_and_cache as tokenize_and_cache\n", + "import jiant.proj.main.export_model as export_model\n", + "import jiant.proj.main.scripts.configurator as configurator\n", + "import jiant.proj.main.runscript as main_runscript\n", + "import jiant.shared.caching as caching\n", + "import jiant.utils.python.io as py_io\n", + "import jiant.utils.display as display\n", + "import os" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "HPZHyLOlVp07" + }, + "source": [ + "#### Download model\n", + "\n", + "Next, we will download a `roberta-base` model. This also includes the tokenizer." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "K06qUGjkKWa7" + }, + "outputs": [], + "source": [ + "export_model.lookup_and_export_model(\n", + " model_type=\"roberta-base\",\n", + " output_base_path=\"./models/roberta-base\",\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "dV-T-8r1V0wf" + }, + "source": [ + "#### Tokenize and cache\n", + "\n", + "With the model and data ready, we can now tokenize and cache the inputs features for our tasks. This converts the input examples to tokenized features ready to be consumed by the model, and saved them to disk in chunks." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "22bNWQajO4zm" + }, + "outputs": [], + "source": [ + "# Tokenize and cache each task\n", + "for task_name in [\"rte\", \"stsb\", \"commonsenseqa\"]:\n", + " tokenize_and_cache.main(tokenize_and_cache.RunConfiguration(\n", + " task_config_path=f\"./tasks/configs/{task_name}_config.json\",\n", + " model_type=\"roberta-base\",\n", + " model_tokenizer_path=\"./models/roberta-base/tokenizer\",\n", + " output_dir=f\"./cache/{task_name}\",\n", + " phases=[\"train\", \"val\"],\n", + " ))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "JJ-mWSQQWJsw" + }, + "source": [ + "We can inspect the first examples of the first chunk of each task." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "iLk_X0KypUyr" + }, + "outputs": [], + "source": [ + "row = caching.ChunkedFilesDataCache(\"./cache/rte/train\").load_chunk(0)[0][\"data_row\"]\n", + "print(row.input_ids)\n", + "print(row.tokens)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "2n00e6Xrp1bI" + }, + "outputs": [], + "source": [ + "row = caching.ChunkedFilesDataCache(\"./cache/stsb/val\").load_chunk(0)[0][\"data_row\"]\n", + "print(row.input_ids)\n", + "print(row.tokens)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "A7FxZgEbqCx-" + }, + "outputs": [], + "source": [ + "row = caching.ChunkedFilesDataCache(\"./cache/commonsenseqa/val\").load_chunk(0)[0][\"data_row\"]\n", + "print(row.input_ids)\n", + "for context_and_choice in row.tokens_list:\n", + " print(context_and_choice)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "3MBuH19IWOr0" + }, + "source": [ + "#### Writing a run config\n", + "\n", + "Here we are going to write what we call a `jiant_task_container_config`. This configuration file basically defines a lot of the subtleties of our training pipeline, such as what tasks we will train on, do evaluation on, batch size for each task. The new version of `jiant` leans heavily toward explicitly specifying everything, for the purpose of inspectability and leaving minimal surprises for the user, even as the cost of being more verbose.\n", + "\n", + "We use a helper \"Configurator\" to write out a `jiant_task_container_config`, since most of our setup is pretty standard. \n", + "\n", + "**Depending on what GPU your Colab session is assigned to, you may need to lower the train batch size.**" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "pQYtl7xTKsiP" + }, + "outputs": [], + "source": [ + "jiant_run_config = configurator.SimpleAPIMultiTaskConfigurator(\n", + " task_config_base_path=\"./tasks/configs\",\n", + " task_cache_base_path=\"./cache\",\n", + " train_task_name_list=[\"rte\", \"stsb\", \"commonsenseqa\"],\n", + " val_task_name_list=[\"rte\", \"stsb\", \"commonsenseqa\"],\n", + " train_batch_size=4,\n", + " eval_batch_size=8,\n", + " epochs=0.5,\n", + " num_gpus=1,\n", + ").create_config()\n", + "os.makedirs(\"./run_configs/\", exist_ok=True)\n", + "py_io.write_json(jiant_run_config, \"./run_configs/jiant_run_config.json\")\n", + "display.show_json(jiant_run_config)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "-UF501yoXHBi" + }, + "source": [ + "To briefly go over the major components of the `jiant_task_container_config`:\n", + "\n", + "* `task_config_path_dict`: The paths to the task config files we wrote above.\n", + "* `task_cache_config_dict`: The paths to the task features caches we generated above.\n", + "* `sampler_config`: Determines how to sample from different tasks during training.\n", + "* `global_train_config`: The number of total steps and warmup steps during training.\n", + "* `task_specific_configs_dict`: Task-specific arguments for each task, such as training batch size and gradient accumulation steps.\n", + "* `taskmodels_config`: Task-model specific arguments for each task-model, including what tasks use which model.\n", + "* `metric_aggregator_config`: Determines how to weight/aggregate the metrics across multiple tasks." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "BBKkvXzdYPqZ" + }, + "source": [ + "#### Start training\n", + "\n", + "Finally, we can start our training run. \n", + "\n", + "Before starting training, the script also prints out the list of parameters in our model. You should notice that there is a unique task head for each task." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "JdwWPgjQWx6I" + }, + "outputs": [], + "source": [ + "run_args = main_runscript.RunConfiguration(\n", + " jiant_task_container_config_path=\"./run_configs/jiant_run_config.json\",\n", + " output_dir=\"./runs/run1\",\n", + " model_type=\"roberta-base\",\n", + " model_path=\"./models/roberta-base/model/roberta-base.p\",\n", + " model_config_path=\"./models/roberta-base/model/roberta-base.json\",\n", + " model_tokenizer_path=\"./models/roberta-base/tokenizer\",\n", + " learning_rate=1e-5,\n", + " eval_every_steps=500,\n", + " do_train=True,\n", + " do_val=True,\n", + " force_overwrite=True,\n", + ")\n", + "\n", + "main_runscript.run_loop(run_args)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "4SXcuHFIYp6Y" + }, + "source": [ + "Finally, we should see the validation scores for all three tasks. We are not winning any awards with these scores, but this example should show how easy it is to run multi-task training in `jiant`." + ] + } + ], + "metadata": { + "accelerator": "GPU", + "colab": { + "collapsed_sections": [], + "name": "jiant Multi-Task Example", + "provenance": [] + }, + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.2" + } + }, + "nbformat": 4, + "nbformat_minor": 1 +} diff --git a/examples/notebooks/jiant_STILTs_Example.ipynb b/examples/notebooks/jiant_STILTs_Example.ipynb new file mode 100644 index 000000000..a779b5726 --- /dev/null +++ b/examples/notebooks/jiant_STILTs_Example.ipynb @@ -0,0 +1,477 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "O9I9rz0pTamX" + }, + "source": [ + "# Sequential Training Example" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "EiowR0WNTd1C" + }, + "source": [ + "[Sequential training](https://arxiv.org/abs/1811.01088v2) involves fine-tuning a language-encoding model (e.g. BERT) on one task (the \"intermediate\" task), and then again on a second task (the \"target\" task). In many cases, the right choice of intermediate task can improve the performance on the target task compared to fine-tuning only on the target task.\n", + "\n", + "Between the two phases of training, we are going to carry over the language encoding model, and not the task heads.\n", + "\n", + "--- \n", + "\n", + "In this notebook, we will:\n", + "\n", + "* Train a RoBERTa base model on MNLI, and the further fine-tune the model on RTE" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "rXbD_U1_VDnw" + }, + "source": [ + "## Setup" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "tC9teoazUnW8" + }, + "source": [ + "#### Install dependencies\n", + "\n", + "First, we will install libraries we need for this code." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "8aU3Z9szuMU9" + }, + "outputs": [], + "source": [ + "%%capture\n", + "!git clone https://github.com/jiant-dev/jiant.git\n", + "!cd jiant\n", + "!git checkout d26c213c742d36f8909f3a910694c8a90da416f1\n", + "!cd .." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "hMUKEH2YvFPv" + }, + "outputs": [], + "source": [ + "%%capture\n", + "# This Colab notebook already has its CUDA-runtime compatible versions of torch and torchvision installed\n", + "!pip install -r jiant/requirements-no-torch.txt\n", + "# Install pyarrow for nlp\n", + "!pip install pyarrow==0.16.0" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "KGJcCmRzU1Qb" + }, + "source": [ + "#### Download data\n", + "\n", + "Next, we will download MNLI and RTE data. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "jKCz8VksvFlN" + }, + "outputs": [], + "source": [ + "%%capture\n", + "# Download MNLI and RTE data\n", + "!PYTHONPATH=/content/jiant python jiant/jiant/scripts/download_data/runscript.py \\\n", + " download \\\n", + " --tasks mnli rte \\\n", + " --output_path=/content/tasks/" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "rQKSAhYzVIlv" + }, + "source": [ + "## `jiant` Pipeline" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "v88oXqmBvFuK" + }, + "outputs": [], + "source": [ + "import sys\n", + "sys.path.insert(0, \"/content/jiant\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "ibmMT7CXv1_P" + }, + "outputs": [], + "source": [ + "import jiant.proj.main.tokenize_and_cache as tokenize_and_cache\n", + "import jiant.proj.main.export_model as export_model\n", + "import jiant.proj.main.scripts.configurator as configurator\n", + "import jiant.proj.main.runscript as main_runscript\n", + "import jiant.shared.caching as caching\n", + "import jiant.utils.python.io as py_io\n", + "import jiant.utils.display as display\n", + "import os" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "HPZHyLOlVp07" + }, + "source": [ + "#### Download model\n", + "\n", + "Next, we will download a `roberta-base` model. This also includes the tokenizer." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "K06qUGjkKWa7" + }, + "outputs": [], + "source": [ + "export_model.lookup_and_export_model(\n", + " model_type=\"roberta-base\",\n", + " output_base_path=\"./models/roberta-base\",\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "dV-T-8r1V0wf" + }, + "source": [ + "#### Tokenize and cache\n", + "\n", + "With the model and data ready, we can now tokenize and cache the inputs features for our tasks. This converts the input examples to tokenized features ready to be consumed by the model, and saved them to disk in chunks." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "22bNWQajO4zm" + }, + "outputs": [], + "source": [ + "# Tokenize and cache each task\n", + "for task_name in [\"mnli\", \"rte\"]:\n", + " tokenize_and_cache.main(tokenize_and_cache.RunConfiguration(\n", + " task_config_path=f\"./tasks/configs/{task_name}_config.json\",\n", + " model_type=\"roberta-base\",\n", + " model_tokenizer_path=\"./models/roberta-base/tokenizer\",\n", + " output_dir=f\"./cache/{task_name}\",\n", + " phases=[\"train\", \"val\"],\n", + " ))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "JJ-mWSQQWJsw" + }, + "source": [ + "We can inspect the first examples of the first chunk of each task." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "iLk_X0KypUyr" + }, + "outputs": [], + "source": [ + "row = caching.ChunkedFilesDataCache(\"./cache/mnli/train\").load_chunk(0)[0][\"data_row\"]\n", + "print(row.input_ids)\n", + "print(row.tokens)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "2n00e6Xrp1bI" + }, + "outputs": [], + "source": [ + "row = caching.ChunkedFilesDataCache(\"./cache/rte/val\").load_chunk(0)[0][\"data_row\"]\n", + "print(row.input_ids)\n", + "print(row.tokens)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "3MBuH19IWOr0" + }, + "source": [ + "#### Writing a run config\n", + "\n", + "Here we are going to write what we call a `jiant_task_container_config`. This configuration file basically defines a lot of the subtleties of our training pipeline, such as what tasks we will train on, do evaluation on, batch size for each task. The new version of `jiant` leans heavily toward explicitly specifying everything, for the purpose of inspectability and leaving minimal surprises for the user, even as the cost of being more verbose.\n", + "\n", + "Since we are training in two phases, we will need to write two run configs - one for MNLI, and one for RTE. (This might seem tedious, but note that these can be easily reusable across different combinations of intermediate and target tasks.)\n", + "\n", + "We use a helper \"Configurator\" to write out a `jiant_task_container_config`, since most of our setup is pretty standard. \n", + "\n", + "We start with the MNLI config:\n", + "\n", + "**Depending on what GPU your Colab session is assigned to, you may need to lower the train batch size.**" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "pQYtl7xTKsiP" + }, + "outputs": [], + "source": [ + "jiant_run_config = configurator.SimpleAPIMultiTaskConfigurator(\n", + " task_config_base_path=\"./tasks/configs\",\n", + " task_cache_base_path=\"./cache\",\n", + " train_task_name_list=[\"mnli\"],\n", + " val_task_name_list=[\"mnli\"],\n", + " train_batch_size=8,\n", + " eval_batch_size=16,\n", + " epochs=0.1,\n", + " num_gpus=1,\n", + ").create_config()\n", + "os.makedirs(\"./run_configs/\", exist_ok=True)\n", + "py_io.write_json(jiant_run_config, \"./run_configs/mnli_run_config.json\")\n", + "display.show_json(jiant_run_config)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "-UF501yoXHBi" + }, + "source": [ + "To briefly go over the major components of the `jiant_task_container_config`:\n", + "\n", + "* `task_config_path_dict`: The paths to the task config files we wrote above.\n", + "* `task_cache_config_dict`: The paths to the task features caches we generated above.\n", + "* `sampler_config`: Determines how to sample from different tasks during training.\n", + "* `global_train_config`: The number of total steps and warmup steps during training.\n", + "* `task_specific_configs_dict`: Task-specific arguments for each task, such as training batch size and gradient accumulation steps.\n", + "* `taskmodels_config`: Task-model specific arguments for each task-model, including what tasks use which model.\n", + "* `metric_aggregator_config`: Determines how to weight/aggregate the metrics across multiple tasks." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "4T-9kuT75V5J" + }, + "source": [ + "Next, we will write the equivalent for RTE." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "lQrT9pm24DZY" + }, + "outputs": [], + "source": [ + "jiant_run_config = configurator.SimpleAPIMultiTaskConfigurator(\n", + " task_config_base_path=\"./tasks/configs\",\n", + " task_cache_base_path=\"./cache\",\n", + " train_task_name_list=[\"rte\"],\n", + " val_task_name_list=[\"rte\"],\n", + " train_batch_size=8,\n", + " eval_batch_size=16,\n", + " epochs=0.5,\n", + " num_gpus=1,\n", + ").create_config()\n", + "os.makedirs(\"./run_configs/\", exist_ok=True)\n", + "py_io.write_json(jiant_run_config, \"./run_configs/rte_run_config.json\")\n", + "display.show_json(jiant_run_config)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "BBKkvXzdYPqZ" + }, + "source": [ + "#### Start training\n", + "\n", + "Finally, we can start our training run. \n", + "\n", + "Before starting training, the script also prints out the list of parameters in our model. In the first phase, we are simply training on MNLI." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "JdwWPgjQWx6I" + }, + "outputs": [], + "source": [ + "run_args = main_runscript.RunConfiguration(\n", + " jiant_task_container_config_path=\"./run_configs/mnli_run_config.json\",\n", + " output_dir=\"./runs/mnli\",\n", + " model_type=\"roberta-base\",\n", + " model_path=\"./models/roberta-base/model/roberta-base.p\",\n", + " model_config_path=\"./models/roberta-base/model/roberta-base.json\",\n", + " model_tokenizer_path=\"./models/roberta-base/tokenizer\",\n", + " learning_rate=1e-5,\n", + " eval_every_steps=500,\n", + " do_train=True,\n", + " do_val=True,\n", + " do_save=True,\n", + " force_overwrite=True,\n", + ")\n", + "main_runscript.run_loop(run_args)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "Dk2KQwNt5fTG" + }, + "source": [ + "The above run saves the best model weights to `./runs/mnli/best_model.p`. Now, we will pick up from those saved model weights and start training on RTE. In addition to changing the `model_path`, we also set `model_load_mode=\"partial\"`. This tells `jiant` that we will not be loading and reusing the task heads from the previous run." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "hmtRJc-84Msh" + }, + "outputs": [], + "source": [ + "run_args = main_runscript.RunConfiguration(\n", + " jiant_task_container_config_path=\"./run_configs/rte_run_config.json\",\n", + " output_dir=\"./runs/mnli___rte\",\n", + " model_type=\"roberta-base\",\n", + " model_path=\"./runs/mnli/best_model.p\", # Loading the best model\n", + " model_load_mode=\"partial\",\n", + " model_config_path=\"./models/roberta-base/model/roberta-base.json\",\n", + " model_tokenizer_path=\"./models/roberta-base/tokenizer\",\n", + " learning_rate=1e-5,\n", + " eval_every_steps=500,\n", + " do_train=True,\n", + " do_val=True,\n", + " force_overwrite=True,\n", + ")\n", + "main_runscript.run_loop(run_args)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "4SXcuHFIYp6Y" + }, + "source": [ + "Finally, we should see the validation scores RTE. You can compare these to just training on RTE and should see a good margin of improvement." + ] + } + ], + "metadata": { + "accelerator": "GPU", + "colab": { + "collapsed_sections": [], + "name": "jiant STILTs Example", + "provenance": [], + "toc_visible": true + }, + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.2" + } + }, + "nbformat": 4, + "nbformat_minor": 1 +} diff --git a/examples/notebooks/jiant_XNLI_Example.ipynb b/examples/notebooks/jiant_XNLI_Example.ipynb new file mode 100644 index 000000000..754bd2894 --- /dev/null +++ b/examples/notebooks/jiant_XNLI_Example.ipynb @@ -0,0 +1,456 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "O9I9rz0pTamX" + }, + "source": [ + "# XNLI Example" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "EiowR0WNTd1C" + }, + "source": [ + "In this notebook, we are going to train a model for evaluating on [XNLI](https://github.com/facebookresearch/XNLI). XNLI a cross-lingual NLI task, spanning 15 different languages, with 10,000 validation and test examples per language. Notably, XNLI does not have its own training set - instead, the usual recipe is to MNLI as a training set, and is then zero-shot evaluated on NLI examples in other languages. Of course, this works best when you start with a model that has already been pretrained on a lot of multi-lingual text, such as mBERT or XLM/XLM-RoBERTa.\n", + "\n", + "Hence, the tricky part about this setup is that although we have separate XNLI and MNLI tasks, we need them to all use the same task head. We will cover how to easily do this with `jiant`.\n", + "\n", + "--- \n", + "\n", + "In this notebook, we will:\n", + "\n", + "* Train an XLM-RoBERTa base model on MNLI\n", + "* Evaluate on XNLI-de (German) and XNLI-zh (Chinese)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "rXbD_U1_VDnw" + }, + "source": [ + "## Setup" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "tC9teoazUnW8" + }, + "source": [ + "#### Install dependencies\n", + "\n", + "First, we will install libraries we need for this code." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "8aU3Z9szuMU9" + }, + "outputs": [], + "source": [ + "%%capture\n", + "!git clone https://github.com/jiant-dev/jiant.git\n", + "!cd jiant\n", + "!git checkout d26c213c742d36f8909f3a910694c8a90da416f1\n", + "!cd .." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "hMUKEH2YvFPv" + }, + "outputs": [], + "source": [ + "%%capture\n", + "# This Colab notebook already has its CUDA-runtime compatible versions of torch and torchvision installed\n", + "!pip install -r jiant/requirements-no-torch.txt\n", + "# Install pyarrow for nlp\n", + "!pip install pyarrow==0.16.0" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "KGJcCmRzU1Qb" + }, + "source": [ + "#### Download data\n", + "\n", + "Next, we will download MNLI and XNLI data. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "jKCz8VksvFlN" + }, + "outputs": [], + "source": [ + "%%capture\n", + "# Download MNLI and XNLI data\n", + "!PYTHONPATH=/content/jiant python jiant/jiant/scripts/download_data/runscript.py \\\n", + " download \\\n", + " --tasks mnli xnli \\\n", + " --output_path=/content/tasks/" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "rQKSAhYzVIlv" + }, + "source": [ + "## `jiant` Pipeline" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "v88oXqmBvFuK" + }, + "outputs": [], + "source": [ + "import sys\n", + "sys.path.insert(0, \"/content/jiant\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "ibmMT7CXv1_P" + }, + "outputs": [], + "source": [ + "import jiant.proj.main.tokenize_and_cache as tokenize_and_cache\n", + "import jiant.proj.main.export_model as export_model\n", + "import jiant.proj.main.scripts.configurator as configurator\n", + "import jiant.proj.main.runscript as main_runscript\n", + "import jiant.shared.caching as caching\n", + "import jiant.utils.python.io as py_io\n", + "import jiant.utils.display as display\n", + "import os" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "HPZHyLOlVp07" + }, + "source": [ + "#### Download model\n", + "\n", + "Next, we will download an `xlm-roberta-base` model. This also includes the tokenizer." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "K06qUGjkKWa7" + }, + "outputs": [], + "source": [ + "export_model.lookup_and_export_model(\n", + " model_type=\"xlm-roberta-base\",\n", + " output_base_path=\"./models/xlm-roberta-base\",\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "dV-T-8r1V0wf" + }, + "source": [ + "#### Tokenize and cache\n", + "\n", + "With the model and data ready, we can now tokenize and cache the inputs features for our tasks. This converts the input examples to tokenized features ready to be consumed by the model, and saved them to disk in chunks.\n", + "\n", + "Note that we are tokenize `train` and `val` data for MNLI, but only `val` data for XNLI, since there is no corresponding training data." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "22bNWQajO4zm" + }, + "outputs": [], + "source": [ + "# Tokenize and cache MNLI\n", + "tokenize_and_cache.main(tokenize_and_cache.RunConfiguration(\n", + " task_config_path=f\"./tasks/configs/mnli_config.json\",\n", + " model_type=\"xlm-roberta-base\",\n", + " model_tokenizer_path=\"./models/xlm-roberta-base/tokenizer\",\n", + " output_dir=f\"./cache/mnli\",\n", + " phases=[\"train\", \"val\"],\n", + "))\n", + "\n", + "# Tokenize and cache XNLI-de, XNLI-zh\n", + "for lang in [\"de\", \"zh\"]:\n", + " tokenize_and_cache.main(tokenize_and_cache.RunConfiguration(\n", + " task_config_path=f\"./tasks/configs/xnli_{lang}_config.json\",\n", + " model_type=\"xlm-roberta-base\",\n", + " model_tokenizer_path=\"./models/xlm-roberta-base/tokenizer\",\n", + " output_dir=f\"./cache/xnli_{lang}\",\n", + " phases=[\"val\"],\n", + " ))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "JJ-mWSQQWJsw" + }, + "source": [ + "We can inspect the first examples of the first chunk of each task." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "iLk_X0KypUyr" + }, + "outputs": [], + "source": [ + "row = caching.ChunkedFilesDataCache(\"./cache/mnli/train\").load_chunk(0)[0][\"data_row\"]\n", + "print(row.input_ids)\n", + "print(row.tokens)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "2n00e6Xrp1bI" + }, + "outputs": [], + "source": [ + "row = caching.ChunkedFilesDataCache(\"./cache/xnli_de/val\").load_chunk(0)[0][\"data_row\"]\n", + "print(row.input_ids)\n", + "print(row.tokens)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "A7FxZgEbqCx-" + }, + "outputs": [], + "source": [ + "row = caching.ChunkedFilesDataCache(\"./cache/xnli_zh/val\").load_chunk(0)[0][\"data_row\"]\n", + "print(row.input_ids)\n", + "print(row.tokens)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "3MBuH19IWOr0" + }, + "source": [ + "#### Writing a run config\n", + "\n", + "Here we are going to write what we call a `jiant_task_container_config`. This configuration file basically defines a lot of the subtleties of our training pipeline, such as what tasks we will train on, do evaluation on, batch size for each task. The new version of `jiant` leans heavily toward explicitly specifying everything, for the purpose of inspectability and leaving minimal surprises for the user, even as the cost of being more verbose.\n", + "\n", + "We use a helper \"Configurator\" to write out a `jiant_task_container_config`, since most of our setup is pretty standard. We specify to train only on MNLI, but evaluate on MNLI, XNLI-de and XNLI-zh.\n", + "\n", + "**Depending on what GPU your Colab session is assigned to, you may need to lower the train batch size.**" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "pQYtl7xTKsiP" + }, + "outputs": [], + "source": [ + "jiant_run_config = configurator.SimpleAPIMultiTaskConfigurator(\n", + " task_config_base_path=\"./tasks/configs\",\n", + " task_cache_base_path=\"./cache\",\n", + " train_task_name_list=[\"mnli\"],\n", + " val_task_name_list=[\"mnli\", \"xnli_de\", \"xnli_zh\"],\n", + " train_batch_size=32,\n", + " eval_batch_size=64,\n", + " epochs=0.1,\n", + " num_gpus=1,\n", + ").create_config()\n", + "display.show_json(jiant_run_config)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "-UF501yoXHBi" + }, + "source": [ + "To briefly go over the major components of the `jiant_task_container_config`:\n", + "\n", + "* `task_config_path_dict`: The paths to the task config files we wrote above.\n", + "* `task_cache_config_dict`: The paths to the task features caches we generated above.\n", + "* `sampler_config`: Determines how to sample from different tasks during training.\n", + "* `global_train_config`: The number of total steps and warmup steps during training.\n", + "* `task_specific_configs_dict`: Task-specific arguments for each task, such as training batch size and gradient accumulation steps.\n", + "* `taskmodels_config`: Task-model specific arguments for each task-model, including what tasks use which model.\n", + "* `metric_aggregator_config`: Determines how to weight/aggregate the metrics across multiple tasks." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "sf9C_RlBX-lK" + }, + "source": [ + "**We need to make one small change to the auto-generated config**: we need to ensure that all three tasks use the same model head. Otherwise, each task will have its own task head, and the XNLI heads will be untrained.\n", + "\n", + "We can make a simple change to the dictionary, setting all of them to point to an `nli_model` head, and then write out the config." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "InlkHBiCTXT9" + }, + "outputs": [], + "source": [ + "jiant_run_config[\"taskmodels_config\"][\"task_to_taskmodel_map\"] = {\n", + " \"mnli\": \"nli_model\",\n", + " \"xnli_de\": \"nli_model\",\n", + " \"xnli_zh\": \"nli_model\",\n", + "}\n", + "os.makedirs(\"./run_configs/\", exist_ok=True)\n", + "py_io.write_json(jiant_run_config, \"./run_configs/jiant_run_config.json\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "BBKkvXzdYPqZ" + }, + "source": [ + "#### Start training\n", + "\n", + "Finally, we can start our training run. \n", + "\n", + "Before starting training, the script also prints out the list of parameters in our model. You should notice that the only task head is the `nli_model` head." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "JdwWPgjQWx6I" + }, + "outputs": [], + "source": [ + "run_args = main_runscript.RunConfiguration(\n", + " jiant_task_container_config_path=\"./run_configs/jiant_run_config.json\",\n", + " output_dir=\"./runs/run1\",\n", + " model_type=\"xlm-roberta-base\",\n", + " model_path=\"./models/xlm-roberta-base/model/xlm-roberta-base.p\",\n", + " model_config_path=\"./models/xlm-roberta-base/model/xlm-roberta-base.json\",\n", + " model_tokenizer_path=\"./models/xlm-roberta-base/tokenizer\",\n", + " learning_rate=1e-5,\n", + " eval_every_steps=500,\n", + " do_train=True,\n", + " do_val=True,\n", + " force_overwrite=True,\n", + ")\n", + "\n", + "main_runscript.run_loop(run_args)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "4SXcuHFIYp6Y" + }, + "source": [ + "Finally, we should see the validation scores for MNLI, XNLI-de, and XNLI-zh. Given that the training data is in English, we expect to see slightly higher scores for MNLI, but the scores for XNLI-de and XNLI-zh are still decent!" + ] + } + ], + "metadata": { + "accelerator": "GPU", + "colab": { + "collapsed_sections": [], + "name": "jiant XNLI Example", + "provenance": [] + }, + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.2" + } + }, + "nbformat": 4, + "nbformat_minor": 1 +} diff --git a/examples/notebooks/simple_api_fine_tuning.ipynb b/examples/notebooks/simple_api_fine_tuning.ipynb new file mode 100644 index 000000000..451ad50cf --- /dev/null +++ b/examples/notebooks/simple_api_fine_tuning.ipynb @@ -0,0 +1,238 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "name": "simple_api_fine_tuning.ipynb", + "provenance": [], + "collapsed_sections": [], + "toc_visible": true + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + }, + "accelerator": "GPU" + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "xT4_NpW-TotE", + "colab_type": "text" + }, + "source": [ + "# Welcome to `jiant`\n", + "This notebook contains an example of fine-tuning a `roberta-base` model on the MRPC task using the simple `jiant` API." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "JlM8H-WCoh9k", + "colab_type": "text" + }, + "source": [ + "# Install dependencies" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "rY-7weGtIEUX", + "colab_type": "code", + "colab": {} + }, + "source": [ + "%%capture\n", + "!git clone https://github.com/jiant-dev/jiant.git\n", + "%cd jiant\n", + "!git checkout 572441964e859d00fa2071c0888dd4ab6a8d3619\n", + "%cd ..\n", + "\n", + "# This Colab notebook already has its CUDA-runtime compatible versions of torch and torchvision installed\n", + "!pip install -r jiant/requirements-no-torch.txt\n", + "# Install pyarrow for nlp (no longer necessary after nlp>0.3.0)\n", + "!pip install pyarrow==0.16.0" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "j78UDhA7UMzi", + "colab_type": "text" + }, + "source": [ + "# Imports" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "5hsmmr9eIJJt", + "colab_type": "code", + "colab": {} + }, + "source": [ + "# To be removed when jiant installed with pip\n", + "import sys\n", + "sys.path.insert(0, \"/content/jiant\")" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "UXYZHyyNGayI", + "colab_type": "code", + "colab": {} + }, + "source": [ + "import os\n", + "\n", + "import jiant.utils.python.io as py_io\n", + "from jiant.proj.simple import runscript as run\n", + "import jiant.scripts.download_data.runscript as downloader" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "aow1wIIDUS4h", + "colab_type": "text" + }, + "source": [ + "# Define task and model" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "AEtgbtkRHDJE", + "colab_type": "code", + "colab": {} + }, + "source": [ + "# See https://github.com/jiant-dev/jiant/blob/master/md_docs/tasks.md for supported tasks\n", + "TASK_NAME = \"mrpc\"\n", + "\n", + "# See https://huggingface.co/models for supported models\n", + "MODEL_TYPE = \"roberta-base\"" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xDjg1tRNUk9r", + "colab_type": "text" + }, + "source": [ + "# Create directories for task data and experiment" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Gxy_csM9UhhA", + "colab_type": "code", + "colab": {} + }, + "source": [ + "RUN_NAME = f\"simple_{TASK_NAME}_{MODEL_TYPE}\"\n", + "DATA_DIR = \"/content/data\"\n", + "EXP_DIR = \"/content/exp\"\n", + "\n", + "os.makedirs(DATA_DIR, exist_ok=True)\n", + "os.makedirs(EXP_DIR, exist_ok=True)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8tXDQ1P2Unfa", + "colab_type": "text" + }, + "source": [ + "#Download data (uses `nlp` or direct download depending on task)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "_HCQG8fEU4CU", + "colab_type": "code", + "colab": {} + }, + "source": [ + "downloader.download_data([TASK_NAME], DATA_DIR)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ZsInlNWLU5ZU", + "colab_type": "text" + }, + "source": [ + "#Run simple `jiant` pipeline (train and evaluate on MRPC)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Po0N521IHAjj", + "colab_type": "code", + "colab": {} + }, + "source": [ + "args = run.RunConfiguration(\n", + " run_name=RUN_NAME,\n", + " exp_dir=EXP_DIR,\n", + " data_dir=DATA_DIR,\n", + " model_type=MODEL_TYPE,\n", + " tasks=TASK_NAME,\n", + " train_batch_size=16,\n", + " num_train_epochs=1\n", + ")\n", + "run.run_simple(args)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2GLUP22PoowE", + "colab_type": "text" + }, + "source": [ + "The simple API `RunConfiguration` object is saved as `simple_run_config.json`. `simple_run_config.json` can be loaded and used as inputs to repeat experiments as follows." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ckhYG6Ijh1nC", + "colab_type": "code", + "colab": {} + }, + "source": [ + "args = run.RunConfiguration.from_json_path(os.path.join(EXP_DIR, \"runs\", RUN_NAME, \"simple_run_config.json\"))\n", + "run.run_simple(args)" + ], + "execution_count": null, + "outputs": [] + } + ] +} diff --git a/gcp/config/auto.master b/gcp/config/auto.master deleted file mode 100644 index ab9e6fcf2..000000000 --- a/gcp/config/auto.master +++ /dev/null @@ -1,31 +0,0 @@ -# -# Sample auto.master file -# This is a 'master' automounter map and it has the following format: -# mount-point [map-type[,format]:]map [options] -# For details of the format look at auto.master(5). -# -#/misc /etc/auto.misc -# -# NOTE: mounts done from a hosts map will be mounted with the -# "nosuid" and "nodev" options unless the "suid" and "dev" -# options are explicitly given. -# -#/net -hosts -# -# Include /etc/auto.master.d/*.autofs -# The included files must conform to the format of this file. -# -+dir:/etc/auto.master.d -# -# Include central master map if it can be found using -# nsswitch sources. -# -# Note that if there are entries for /net or /misc (as -# above) in the included master map any keys that are the -# same will not be seen as the first read key seen takes -# precedence. -# -+auto.master - -/nfs /etc/auto.nfs --timeout=300 - diff --git a/gcp/config/auto.nfs b/gcp/config/auto.nfs deleted file mode 100644 index ef391fb72..000000000 --- a/gcp/config/auto.nfs +++ /dev/null @@ -1,3 +0,0 @@ -# Change this to the NFS server on your cluster -jiant -rw,hard jiant:/jiant - diff --git a/gcp/config/jiant_paths.sh b/gcp/config/jiant_paths.sh deleted file mode 100644 index dcd43eb1d..000000000 --- a/gcp/config/jiant_paths.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/bash - -# Copy this to /etc/profile.d/ to auto-set environment vars on login. - -# Default environment variables for jiant. May be overwritten by user. -# See https://github.com/nyu-mll/jiant for more. - -# Default location for glue_data -export JIANT_DATA_DIR="/nfs/jiant/share/glue_data" -# Default experiment parent directory -export JIANT_PROJECT_PREFIX="$HOME/exp" - -# pre-downloaded ELMo models -export ELMO_SRC_DIR="/nfs/jiant/share/elmo" -# cache for BERT etc. models -export HUGGINGFACE_TRANSFORMERS_CACHE="/nfs/jiant/share/transformers_cache" -export PYTORCH_TRANSFORMERS_CACHE="/nfs/jiant/share/transformers_cache" -# word embeddings -export WORD_EMBS_FILE="/nfs/jiant/share/wiki-news-300d-1M.vec" - diff --git a/gcp/create_instance.sh b/gcp/create_instance.sh deleted file mode 100755 index 757069aa3..000000000 --- a/gcp/create_instance.sh +++ /dev/null @@ -1,58 +0,0 @@ -#!/bin/bash - -# Helper script to create a GCP instance from one of the default templates - -# Usage: ./create_instance.sh [] -# Instance type is one of: -# workstation : CPU workstation -# gpu-1 : single-GPU worker -# gpu-2 : double-GPU worker -# gpu-4 : quad-GPU worker -INSTANCE_TYPE="${1:-'gpu-1'}" -INSTANCE_NAME="${2}" -ZONE="${3:-"us-east1-c"}" - -set -e - -if [ -z $INSTANCE_NAME ]; then - echo "You must provide an instance name!" - exit 1 -fi - -if [[ $INSTANCE_TYPE == "cpu" || $INSTANCE_TYPE == "workstation" ]]; then - TEMPLATE="cpu-workstation-template" -elif [[ $INSTANCE_TYPE == "cpu-mini" ]]; then - TEMPLATE="cpu-workstation-template-mini" -elif [[ $INSTANCE_TYPE == "gpu-1l" ]]; then - TEMPLATE="gpu-worker-template-1large" -elif [[ $INSTANCE_TYPE == "gpu-1xl" ]]; then - TEMPLATE="gpu-worker-template-1xlarge" -elif [[ $INSTANCE_TYPE == "gpu-1" ]]; then - TEMPLATE="gpu-worker-template-1" -elif [[ $INSTANCE_TYPE == "gpu-2" ]]; then - TEMPLATE="gpu-worker-template-2" -elif [[ $INSTANCE_TYPE == "gpu-4" ]]; then - TEMPLATE="gpu-worker-template-4" -elif [[ $INSTANCE_TYPE == "gpu-k1" ]]; then - TEMPLATE="gpu-worker-template-k1" -elif [[ $INSTANCE_TYPE == "gpu-k2" ]]; then - TEMPLATE="gpu-worker-template-k2" -elif [[ $INSTANCE_TYPE == "gpu-k4" ]]; then - TEMPLATE="gpu-worker-template-k4" -elif [[ $INSTANCE_TYPE == "gpu-v1" ]]; then - TEMPLATE="gpu-worker-template-v1" -elif [[ $INSTANCE_TYPE == "gpu-v1large" ]]; then - TEMPLATE="gpu-worker-template-v1large" -else - echo "Unsupported instance type '$INSTANCE_TYPE'" - exit 1 -fi - -set -x -gcloud compute instances create "$INSTANCE_NAME" \ - --zone "$ZONE" --source-instance-template "$TEMPLATE" -set +x - -echo "Instance created! Wait a minute or two before attempting to SSH." -STATUS_URL="https://console.cloud.google.com/compute/instancesDetail/zones/$ZONE/instances/$INSTANCE_NAME" -echo "You can monitor status at: $STATUS_URL" diff --git a/gcp/kubernetes/README.md b/gcp/kubernetes/README.md deleted file mode 100644 index 7ddea0b00..000000000 --- a/gcp/kubernetes/README.md +++ /dev/null @@ -1,202 +0,0 @@ -# `jiant` on GKE - -This directory contains configuration files and scripts for running a Kubernetes cluster on Google Kubernetes Engine (GKE) that can run our training and evaluation code. This is a convenient way to get an auto-scaling batch scheduler. - -You may be referring to this guide for several reasons: - -* You should probably check the prerequisites regardless: [Prerequisites](#Prerequisites) -* If you are looking to start *from scratch*, including building a Docker image: [Creating a Docker Image](#creating-a-docker-image) -* If you are looking to start a GKE cluster + NFS from an existing image: [Creating a GKE Cluster + NFS](#creating-a-gke-cluster--nfs) -* If you are looking to access an existing GKE cluster for the first time: [Using an existing GKE cluster](#using-an-existing-gke-cluster) - -For more on Kubernetes, see [this comic](https://cloud.google.com/kubernetes-engine/kubernetes-comic/) and the [GKE quick-start guide](https://cloud.google.com/kubernetes-engine/docs/quickstart). - -====== - -# Prerequisites - -### Workstation - -All setup instructions for the work station assume you are using a Google Compute Engine (GCE) instance (e.g. "Deep Learning with Linux" for the OS), but should also work on any Ubuntu machine with the Google Cloud SDK installed. We suggest you search for one with Docker, nvidia-docker, kubectl, and Pytorch installed, such as "Deep Learning Image: PyTorch 1.2.0" image. - -We recommend that you create a lightweight GCP instance in the same region as your desired cluster. Select "Allow full access to all Cloud APIs" if possible. - -### jsonnet - -Once you are on your workstation, several of the Kubernetes scripts use [jsonnet](https://jsonnet.org/) for configuration. To install the jsonnet command-line utility, you need to build it from source and add it to your system path: -``` -git clone https://github.com/google/jsonnet.git jsonnet -cd jsonnet -make -sudo cp jsonnet /usr/bin -``` - -====== - -# Creating a Docker Image - -### Library setup - -_If you're using the "Deep Learning Image: PyTorch 1.2.0" VM image on Google Cloud Platform, you should already have Docker, nvidia-docker, and kubectl installed, and you can skip the rest of this section._ - -First, install Docker community edition: -```sh -wget https://download.docker.com/linux/ubuntu/dists/xenial/pool/stable/amd64/docker-ce_18.06.1~ce~3-0~ubuntu_amd64.deb -sudo dpkg -i docker-ce_18.06.1~ce~3-0~ubuntu_amd64.deb -``` -Be sure to match the version exactly because this is required for `nvidia-docker` - -Second, install `nvidia-docker` to [enable GPU support](https://github.com/NVIDIA/nvidia-docker): -```sh -# Add the package repositories -curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | \ - sudo apt-key add - -distribution=$(. /etc/os-release;echo $ID$VERSION_ID) -curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | \ - sudo tee /etc/apt/sources.list.d/nvidia-docker.list -sudo apt-get update - -# Install nvidia-docker2 and reload the Docker daemon configuration -sudo apt-get install -y nvidia-docker2 -sudo pkill -SIGHUP dockerd - -# Test nvidia-smi with the latest official CUDA image -docker run --runtime=nvidia --rm nvidia/cuda nvidia-smi -``` - -Finally, install `kubectl` so you can connect to a Kubernetes cluster: -```sh -sudo snap install kubectl --classic -``` - -### Docker Image - -Build the Docker image containing all the library dependencies and environment variables for `jiant`: - -```sh -cd /path/to/jiant -# is your Google Cloud project (e.g. jsalt-sentence-rep) -sudo docker build -t gcr.io//jiant:v1 . -``` - -You may have to use `sudo` for the following. Authenticate to Google Cloud so we can push containers to Google Container Registry (GCR), where they are accessible to Kubernetes nodes: -```sh -gcloud auth configure-docker -``` - -Now push the image that we built locally: -```sh -gcloud docker -- push gcr.io//jiant:v1 -``` -You can keep track of uploaded images by going to Cloud Console -> Container Engine. - -_**Note:** you should update [`templates/jiant_env.libsonnet`](templates/jiant_env.libsonnet) with the name of this container (`gcr.io/...`), so that the job templates will use it correctly._ - -====== - -# Creating a GKE Cluster + NFS - -Before starting this section, you should have a URL (`gcr.io/XXXX`) to a Docker image. - -### GKE Cluster - -Go to [Google Cloud Console](https://cloud.google.com/console) in your browser, go to **Kubernetes Engine**, and create a cluster. We recommend giving each node at least 13 GB of RAM, or 26 GB for GPU workers. If you want to run on GPUs, we recommend creating a pool with either P100s or K80s, and enabling autoscaling. - -Authenticate to the cluster: -```sh -gcloud container clusters get-credentials --zone -``` - -(If you run into an "Insufficient Scope" error, run `gcloud init` and authenticate with the relevant account.) - -Now you can run a simple test job: -```sh -kubectl run hello-world --generator=job/v1 --image gcr.io/XXXX --restart=Never -- echo "Hello World!" -``` - -You should see a workload named `hello-world` in the Kubernetes Engine -> Workloads page, and if you click through to container logs you should see the output of your command. - -If you want to scale back your cluster, follow these [instructions](https://stackoverflow.com/questions/46838221/how-to-stop-a-kubernetes-cluster). - -### NFS Setup - -Go to [Google Cloud Console](cloud.google.com/console) in your browser, go to **Filestore**, and create a Filestore instance in the same region as your cluster. Take note of the `IP Address`, `Fileshare name`, `Instance ID` and `capacity`. - -Modify [`config/auto.nfs`](config/auto.nfs): - -``` -jiant -rw,hard :/ -``` - -Go to `/path/to/jiant/gcp` and run - -```bash -./mount_nfs.sh -``` - -You should see some basic folders in `/nfs/jiant`. Take this opportunity to do some setup of the NFS, such as: - -1. Pull in the relevant task data and save them to `/nfs/jiant/data_dir` -2. Create `/nfs/jiant/home/${USER}` folder, and git clone `jiant`. This should be your working copy of `jiant` hereafter (including for the subsequent step). You may want to repeat the above modification of [`config/auto.nfs`](config/auto.nfs) for that copy of `jiant` too. -3. Create `/nfs/jiant/exp/${USER}` folder - -### Kubernetes Configuration Update - -Now, go to ``/nfs/jiant/${USER}/gcp/kubernetes``. Modify [`templates/jiant_env.libsonnet`](templates/jiant_env.jsonnet): - -* Set `nfs_server_ip` to the Filestore IP Address. -* Set `nfs_server_path` to the Filestore Fileshare name. -* Set `nfs_volume_name` to the Filestore Instance ID. -* Set `nfs_volume_size` to the Filestore capacity. -* Set `gcr_image` to the Docker image URL. - -### Final cluster set-up - -Finally, run: - -```bash -./init_cluster.sh -``` - -This does two things: - -- It adds a DaemonSet that installs GPU drivers on each node. -- It sets up a PersistentVolume that defines the NFS volume in a way Kubernetes - can understand, and sets up a PersistentVolumeClaim that allows jobs to access it. - -====== - -### Running Jobs - -To run jobs, ensure that you have NFS mounted at `/nfs/jiant`, and go to `/nfs/jiant/${USER}/gcp/kubernetes` - -We can schedule basic jobs on the cluster using `kubectl run` as in the "Hello World" example above, but in order to use GPUs and access NFS we need to use a full-fledged YAML config. - -The `run_batch.sh` script handles creating an appropriate config on the fly; see the documentation in that file for more details. Basic usage is: - -```sh -export JIANT_PATH="/nfs/jiant/home/$USER/jiant" -./run_batch.sh \ - "python $JIANT_PATH/main.py --config_file $JIANT_PATH/jiant/config/demo.conf --overrides 'run_name = kubernetes-demo, target_tasks = \"wnli,commitbank\"'" -``` - -You should see your job as `` in Kubernetes Engine -> Workloads, and can monitor status, resource usage, and logs from that page. - -There are also additional options, such as for sending jobs to different GPU types, and deleting jobs (pods in Kubernetes terminology). - -====== - -### Using an existing GKE cluster - -If someone has already set up a GKE cluster for `jiant`, and you have a different set of things to do: - -1. Create a lightweight GCP instance and SSH into it. git clone `jiant`. -2. Get the Filestore IP Address and Fileshare name from the cluster owner, and mount the NFS as in [NFS Setup](#nfs-setup). This includes modifying [`config/auto.nfs`](config/auto.nfs) as directed. -3. Set up up your home folder in `/nfs/jiant/home/${USER}`, and clone jiant to `/nfs/jiant/home/${USER}/jiant`. This will be your working copy of `jiant` hereafter. -4. Create `/nfs/jiant/exp/${USER}` -5. Authenticate to the cluster: - ```sh - gcloud container clusters get-credentials --zone - ``` - If you run into an "Insufficient Scope" error, run `gcloud init` and authenticate with the relevant account. -6. Run jobs as in [Running Jobs](#running-jobs). diff --git a/gcp/kubernetes/init_cluster.sh b/gcp/kubernetes/init_cluster.sh deleted file mode 100755 index 5ed0b1ce0..000000000 --- a/gcp/kubernetes/init_cluster.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/bash - -# Run this on a new Kubernetes cluster. See README.md for details. - -pushd "$(dirname $0)" - -kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/master/nvidia-driver-installer/cos/daemonset-preloaded.yaml - -YAML_STREAM=$( jsonnet -S templates/nfs.jsonnet ) -echo "$YAML_STREAM" -echo "$YAML_STREAM" | kubectl apply -f - - diff --git a/gcp/kubernetes/run_batch.sh b/gcp/kubernetes/run_batch.sh deleted file mode 100755 index 61b2c2105..000000000 --- a/gcp/kubernetes/run_batch.sh +++ /dev/null @@ -1,101 +0,0 @@ -#!/bin/bash - -# Run a job on the Kubernetes cluster. -# -# Before running, be sure that: -# - you're authenticated to the cluster via -# gcloud container clusters get-credentials --zone us-east1-c -# - the resources defined in templates/jiant_env.libsonnet are correct -# -# Example usage: -# export JIANT_PATH="/nfs/jiant/home/$USER/jiant" -# ./run_batch.sh "python $JIANT_PATH/main.py \ -# --config_file $JIANT_PATH/jiant/config/demo.conf \ -# --notify " -# -# You can specify additional arguments as flags: -# -m # mode is 'create', 'replace', 'delete' -# -g # e.g. 'k80' or 'p100' -# -p # project folder to group experiments -# -n # email address for job notifications -# -# For example: -# ./run_batch.sh -p demos -m k80 jiant-demo \ -# "python $JIANT_PATH/main.py --config_file $JIANT_PATH/jiant/config/demo.conf" -# -# will run as job name 'demos.jiant-demo' and write results to /nfs/jsalt/exp/demos -# -set -e - -KUBECTL_MODE="create" -GPU_TYPE="p100" -PROJECT_NAME="$USER" -NOTIFY_EMAIL="" - -# Get the NFS path from the Kubernetes config, so that it doesn't need to be -# hardcoded here. -pushd $(dirname $0)/templates -NFS_EXP_DIR=$(jsonnet -S -e "local env = import 'jiant_env.libsonnet'; env.nfs_exp_dir") -echo "Assuming NFS experiment path at $NFS_EXP_DIR" -popd - -# Handle flags. -OPTIND=1 # Reset in case getopts has been used previously in the shell. -while getopts ":m:g:p:n:" opt; do - case "$opt" in - m) KUBECTL_MODE=$OPTARG - ;; - g) GPU_TYPE=$OPTARG - ;; - p) PROJECT_NAME=$OPTARG - ;; - n) NOTIFY_EMAIL=$OPTARG - ;; - \? ) - echo "Invalid flag $opt." - exit 1 - ;; - esac -done -shift $((OPTIND-1)) - -# Remaining positional args. -NAME=$1 -COMMAND=$2 - -JOB_NAME="${USER}.${PROJECT_NAME}.${NAME}" - -## -# Create project directory, if it doesn't exist yet. -PROJECT_DIR="${NFS_EXP_DIR}/${USER}/${PROJECT_NAME}" -if [ ! -d "${NFS_EXP_DIR}/$USER" ]; then - mkdir "${NFS_EXP_DIR}/$USER" -fi -if [ ! -d "${PROJECT_DIR}" ]; then - echo "Creating project directory ${PROJECT_DIR}" - mkdir ${PROJECT_DIR} - chmod -R o+w ${PROJECT_DIR} -fi - -## -# Create custom config and save to project_dir. -YAML_DIR="${PROJECT_DIR}/yaml" -if [ ! -d "${YAML_DIR}" ]; then - echo "Creating Kubernetes YAML ${YAML_DIR}" - mkdir "${YAML_DIR}" -fi -# set -x # uncomment for debugging -YAML_FILE="${PROJECT_DIR}/yaml/${JOB_NAME}.yaml" -jsonnet -S -o "${YAML_FILE}" \ - --tla-str job_name="${JOB_NAME}" \ - --tla-str command="${COMMAND}" \ - --tla-str project_dir="${PROJECT_DIR}" \ - --tla-str notify_email="${NOTIFY_EMAIL}" \ - --tla-str uid="${UID}" \ - --tla-str fsgroup="${GROUPS}" \ - --tla-str gpu_type="${GPU_TYPE}" \ - "$(dirname $0)/templates/run_batch.jsonnet" - -## -# Create the Kubernetes pod; this will actually launch the job. -kubectl ${KUBECTL_MODE} -f "${YAML_FILE}" diff --git a/gcp/kubernetes/templates/jiant_env.libsonnet b/gcp/kubernetes/templates/jiant_env.libsonnet deleted file mode 100644 index f8388317f..000000000 --- a/gcp/kubernetes/templates/jiant_env.libsonnet +++ /dev/null @@ -1,27 +0,0 @@ -# Shared variables describing the Kubernetes environment. -# You'll likely need to change these if setting up jiant on a new cluster. -{ - # NFS server information. - nfs_server_ip: "10.87.154.18", - nfs_server_path: "/data", - nfs_volume_name: "nfs-jiant", - nfs_volume_size: "2.5T", - - # Mount point for the NFS volume, as the container will see it. - nfs_mount_path: "/nfs/jiant", - - # Default experiment directory; must be writable by Kubernetes workers. - nfs_exp_dir: "/nfs/jiant/exp", - - # Name of pre-built Docker image, accessible from Kubernetes. - gcr_image: "gcr.io/google.com/jiant-stilts/jiant-conda:v2", - - # Default location for glue_data - jiant_data_dir: "/nfs/jiant/share/glue_data", - # Path to ELMO cache. - elmo_src_dir: "/nfs/jiant/share/elmo", - # Path to BERT etc. model cache; should be writable by Kubernetes workers. - transformers_cache_path: "/nfs/jiant/share/transformers_cache", - # Path to default word embeddings file - word_embs_file: "/nfs/jiant/share/wiki-news-300d-1M.vec", -} diff --git a/gcp/kubernetes/templates/nfs.jsonnet b/gcp/kubernetes/templates/nfs.jsonnet deleted file mode 100644 index 57181778c..000000000 --- a/gcp/kubernetes/templates/nfs.jsonnet +++ /dev/null @@ -1,29 +0,0 @@ -local jiant_env = import 'jiant_env.libsonnet'; - -std.manifestYamlStream([ - # Define persistent volume - { - apiVersion: "v1", - kind: "PersistentVolume", - metadata: { name: jiant_env.nfs_volume_name, }, - spec: { - capacity: { storage: jiant_env.nfs_volume_size, }, - accessModes: [ "ReadWriteMany" ], - nfs: { - path: jiant_env.nfs_server_path, - server: jiant_env.nfs_server_ip, - }, - }, - }, - # Define persistent volume claim - { - apiVersion: "v1", - kind: "PersistentVolumeClaim", - metadata: { name: jiant_env.nfs_volume_name + "-claim", }, - spec: { - accessModes: [ "ReadWriteMany" ], - storageClassName: "", - resources: { requests: { storage: jiant_env.nfs_volume_size } } - }, - }, -]) diff --git a/gcp/kubernetes/templates/run_batch.jsonnet b/gcp/kubernetes/templates/run_batch.jsonnet deleted file mode 100644 index c38638479..000000000 --- a/gcp/kubernetes/templates/run_batch.jsonnet +++ /dev/null @@ -1,75 +0,0 @@ -local jiant_env = import 'jiant_env.libsonnet'; - -# Run a jiant job (or anything, really) with the correct path and NFS set-up. -function(job_name, command, project_dir, uid, fsgroup, - notify_email="", gpu_type="p100") std.manifestYamlDoc({ - apiVersion: "v1", - kind: "Pod", - metadata: { name: job_name }, - spec: { - restartPolicy: "Never", - securityContext: { - runAsUser: std.parseInt(uid), - fsGroup: std.parseInt(fsgroup) - }, - containers: [{ - name: 'jiant', - image: jiant_env.gcr_image, - command: ["bash"], - args: ["-l", "-c", command], - # Use one GPU. - resources: { limits: { "nvidia.com/gpu": 1 } }, - # Mount the NFS volume inside the container. - volumeMounts: [ - { - mountPath: jiant_env.nfs_mount_path, - name: jiant_env.nfs_volume_name, - }, - ], - # Environment variables used by jiant - env: [ - { name: "JIANT_PROJECT_PREFIX", value: project_dir }, - { name: "NOTIFY_EMAIL", value: notify_email }, - { - name: "JIANT_DATA_DIR", - value: jiant_env.jiant_data_dir, - }, - { - name: "HUGGINGFACE_TRANSFORMERS_CACHE", - value: jiant_env.transformers_cache_path - }, - { - name: "PYTORCH_TRANSFORMERS_CACHE", - value: jiant_env.transformers_cache_path - }, - { - name: "ELMO_SRC_DIR", - value: jiant_env.elmo_src_dir, - }, - { - name: "WORD_EMBS_FILE", - value: jiant_env.word_embs_file, - }, - ] - }], - # Make sure we request GPU nodes of the correct type. - nodeSelector: { - "cloud.google.com/gke-accelerator": "nvidia-tesla-" + gpu_type, - }, - # Make sure Kubernetes allows us to schedule on GPU nodes. - tolerations: [{ - key: "nvidia.com/gpu", - operator: "Equal", - value: "present", - effect: "NoSchedule", - }], - # Connect the pod to the NFS claim on Kubernetes. - volumes: [{ - name: jiant_env.nfs_volume_name, - persistentVolumeClaim: { - claimName: jiant_env.nfs_volume_name + "-claim", - readOnly: false, - }, - }], - }, -}) diff --git a/gcp/mount_nfs.sh b/gcp/mount_nfs.sh deleted file mode 100644 index 0694c8e6b..000000000 --- a/gcp/mount_nfs.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash - -# Mounts NFS at /nfs/jiant -# Ensure that config/auto.nfs has been updated with the correct IP Address and Fileshare name. - -set -e -set -x - -# Set up NFS automount -sudo apt-get -y install nfs-common autofs -sudo cp -f config/auto.master /etc -sudo cp -f config/auto.nfs /etc - -# Reload autofs daemon and check mount -sudo /etc/init.d/autofs restart -echo "Checking NFS mount at /nfs/jiant. You should see files:" -ls -l /nfs/jiant -echo "" \ No newline at end of file diff --git a/gcp/remote_job.sh b/gcp/remote_job.sh deleted file mode 100755 index ecfa5c80e..000000000 --- a/gcp/remote_job.sh +++ /dev/null @@ -1,44 +0,0 @@ -#!/bin/bash - -# Convenience script to execute a command (such as a training script) remotely -# on a worker instance. - -# This is the simple version, which runs "synchronously": -# the current shell controls the process, and hitting Ctrl+C will kill the -# command (as will losing the SSH connection). -# For persistence, use remote_job_tmux.sh - -# Usage: ./remote_job.sh [] -INSTANCE_NAME="${1}" -COMMAND="${2:-"nvidia-smi"}" -ZONE="${3:-"us-east1-c"}" - -set -e - -if [ -z $INSTANCE_NAME ]; then - echo "You must provide an instance name!" - exit 1 -fi - -FULL_COMMAND="bash -l -c \"${COMMAND}\"" - -declare -a CL_ARGS - -# Use internal ip between GCE instances. -# We use a DNS lookup to tell if the local host is a GCE instance. See -# https://stackoverflow.com/questions/30911775/how-to-know-if-a-machine-is-an-google-compute-engine-instance -dig_response=$(dig +short metadata.google.internal) -if [[ "$dig_response" != "" ]]; then - CL_ARGS+=( --internal-ip ) -fi -CL_ARGS+=( "${INSTANCE_NAME}" ) -CL_ARGS+=( --command "${FULL_COMMAND}" ) -CL_ARGS+=( --zone "$ZONE") -CL_ARGS+=( -- -t ) - -set -x -gcloud beta compute ssh "${CL_ARGS[@]}" - -set +x -echo "Remote command completed successfully." - diff --git a/gcp/remote_job_tmux.sh b/gcp/remote_job_tmux.sh deleted file mode 100755 index f5755d706..000000000 --- a/gcp/remote_job_tmux.sh +++ /dev/null @@ -1,61 +0,0 @@ -#!/bin/bash - -# Convenience script to execute a command (such as a training script) remotely -# on a worker instance. - -# This version creates a tmux session on the remote machine and runs the command -# in it. This gives persistence: if you disconnect from the remote machine, the -# job will continue running. -# -# To exit the tmux session on the remote host, press Ctrl+b followed by the 'd' -# key. To re-attach, you can ssh to the remote host and run: -# tmux attach -t -# Or run this script with the command 'A' -# -# To kill a target job and its associated tmux session, run with the command 'K'. - -# Usage: ./remote_job_tmux.sh [] -INSTANCE_NAME="${1}" -JOB_NAME="${2}" -COMMAND="${3:-"a"}" -ZONE="${4:-"us-east1-c"}" - -set -e - -if [ -z $INSTANCE_NAME ]; then - echo "You must provide an instance name!" - exit 1 -fi -if [ -z $JOB_NAME ]; then - echo "You must provide a job name!" - exit 1 -fi - -if [[ $COMMAND == "A" || $COMMAND == "a" ]]; then - FULL_COMMAND="tmux attach -t ${JOB_NAME}" -elif [[ $COMMAND == "K" || $COMMAND == "k" ]]; then - FULL_COMMAND="tmux kill-session -t ${JOB_NAME}" -else - FULL_COMMAND="tmux new -s ${JOB_NAME} -d; " - FULL_COMMAND+="tmux send '$COMMAND' Enter; " - FULL_COMMAND+="tmux attach -t ${JOB_NAME}" -fi - -declare -a CL_ARGS - -# Use internal ip between GCE instances. -# We use a DNS lookup to tell if the local host is a GCE instance. See -# https://stackoverflow.com/questions/30911775/how-to-know-if-a-machine-is-an-google-compute-engine-instance -dig_response=$(dig +short metadata.google.internal) -if [[ "$dig_response" != "" ]]; then - CL_ARGS+=( --internal-ip ) -fi -CL_ARGS+=( "${INSTANCE_NAME}" ) -CL_ARGS+=( --command "${FULL_COMMAND}" ) -CL_ARGS+=( --zone "$ZONE") -CL_ARGS+=( -- -t ) - -set -x -gcloud beta compute ssh "${CL_ARGS[@]}" - - diff --git a/gcp/set_up_workstation.sh b/gcp/set_up_workstation.sh deleted file mode 100755 index 36f2260c3..000000000 --- a/gcp/set_up_workstation.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/bash - -# Set up a new workstation to use jiant -# Assumes that you've used the "Deep Learning Image: PyTorch 1.1.0" available on -# Google Cloud Platform, and that you have an NFS volume mounted at /nfs/jiant. - -# Copy environment variables and set up paths -sudo cp -f config/jiant_paths.sh /etc/profile.d/jiant_paths.sh -source /etc/profile.d/jiant_paths.sh -if [ ! -d "${JIANT_PROJECT_PREFIX}" ]; then - mkdir "${JIANT_PROJECT_PREFIX}" -fi -if [ ! -d "${HUGGINGFACE_TRANSFORMERS_CACHE}" ]; then - sudo mkdir -m 0777 -p "${HUGGINGFACE_TRANSFORMERS_CACHE}" -fi -if [ ! -d "${PYTORCH_TRANSFORMERS_CACHE}" ]; then - sudo mkdir -m 0777 -p "${PYTORCH_TRANSFORMERS_CACHE}" -fi - - -# Build the conda environment, and activate -pushd .. -conda env create -f environment.yml -conda activate jiant -# Register a kernel for notebooks -ipython kernel install --user --name=jiant - -# Install SpaCy and NLTK models -python -m spacy download en -python -m nltk.downloader perluniprops nonbreaking_prefixes - -echo "Set-up complete! You may need to run 'source /etc/profile.d/jiant_paths.sh', or log out and log back in for things to work." - diff --git a/gcp/transfer_code.sh b/gcp/transfer_code.sh deleted file mode 100755 index 68305231a..000000000 --- a/gcp/transfer_code.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/bash - -# Convenience script to copy this jiant repo to a (new) GCE instance. -# Usage: ./transfer_code.sh [] -echo "FRIENDLY WARNING: Your life will be easier if you keep your code of NFS and maintain only one copy." - -INSTANCE_NAME="${1:-"$USER"}" -ZONE="${2:-"us-east1-c"}" - -set -e - -if [ -z $INSTANCE_NAME ]; then - echo "You must provide an instance name!" - exit 1 -fi - -# Get parent dir of this script's dir -JIANT_DIR=$(cd `dirname $0`/../; pwd) - -set -x -gcloud compute scp --project jsalt-sentence-rep --zone "$ZONE" \ - --recurse $JIANT_DIR "$INSTANCE_NAME:~" - -echo "Transfer completed successfully." diff --git a/guides/benchmarks/glue.md b/guides/benchmarks/glue.md new file mode 100644 index 000000000..f89231e9b --- /dev/null +++ b/guides/benchmarks/glue.md @@ -0,0 +1,13 @@ +# GLUE Benchmark Submission Formatter + +`jiant` supports generating submission files for [GLUE](https://gluebenchmark.com/). To generate test predictions, use the `--write_test_preds` flag in [`runscript.py`](https://github.com/jiant-dev/jiant/blob/master/jiant/proj/main/runscript.py) when running your workflow. This will generate a `test_preds.p` file in the specified output directory. To convert `test_preds.p` to the required GLUE submission format, use the following command: + +```bash +python benchmark_submission_formatter.py --benchmark GLUE --input_base_path $INPUT_BASE_PATH --output_path $OUTPUT_BASE PATH +``` + +where `$INPUT_BASE_PATH` contains the task folder(s) output by [runscript.py](https://github.com/jiant-dev/jiant/blob/master/jiant/proj/main/runscript.py). Alternatively, a subset of tasks can be formatted using: + +```bash +python benchmark_submission_formatter.py --benchmark GLUE --tasks cola mrpc --input_base_path $INPUT_BASE_PATH --output_path $OUTPUT_BASE PATH +``` diff --git a/guides/benchmarks/superglue.md b/guides/benchmarks/superglue.md new file mode 100644 index 000000000..adf0b231f --- /dev/null +++ b/guides/benchmarks/superglue.md @@ -0,0 +1,13 @@ +# SuperGLUE Benchmark Submission Formatter + +`jiant` supports generating submission files for [SuperGLUE](https://super.gluebenchmark.com/). To generate test predictions, use the `--write_test_preds` flag in [`runscript.py`](https://github.com/jiant-dev/jiant/blob/master/jiant/proj/main/runscript.py) when running your workflow. This will generate a `test_preds.p` file in the specified output directory. To convert `test_preds.p` to the required GLUE submission format, use the following command: + +```bash +python benchmark_submission_formatter.py --benchmark SUPERGLUE --input_base_path $INPUT_BASE_PATH --output_path $OUTPUT_BASE PATH +``` + +where `$INPUT_BASE_PATH` contains the task folder(s) output by [runscript.py](https://github.com/nyu-mll/jiant/blob/master/jiant/proj/main/runscript.py). Alternatively, a subset of tasks can be formatted using: + +```bash +python benchmark_submission_formatter.py --benchmark SUPERGLUE --tasks cola mrpc --input_base_path $INPUT_BASE_PATH --output_path $OUTPUT_BASE PATH +``` diff --git a/guides/benchmarks/xtreme.md b/guides/benchmarks/xtreme.md new file mode 100644 index 000000000..d277f49a6 --- /dev/null +++ b/guides/benchmarks/xtreme.md @@ -0,0 +1,59 @@ +# XTREME Running / Submission Guide + +This guide will walk through the full process for evaluating XLM-R on all [XTREME](https://sites.research.google/xtreme/) tasks. It consists of the following steps: + +* [Download Model](#download-model) +* [Download Data](#download-data) +* [Tokenize and Cache Data](#tokenize-and-cache-data) +* [Generate Run Configs](#generate-run-configs) +* [Train/Run Models](#trainrun-models) + +You can also choose to just run one of the tasks, instead of the whole benchmark. + +This code is largely based on the [reference implementation](https://github.com/google-research/xtreme) for the XTREME benchmark. + +Before we begin, be sure to set the following environment variables: +```bash +BASE_PATH=/path/to/xtreme/experiments +MODEL_TYPE=xlm-roberta-large +``` + +We will link to bash **code snippets** in the section below. We recommend that you open them side-by-side with this README when reading them. They should also all work if you run them all in order, after setting the above environment variables. + +## Download Model + +First, we download the model we want to us. From the `MODEL_TYPE` variable above, we are using `xlm-roberta-large`. + +See: [**Code snippet**](jiant/scripts/benchmark_postproc/subscripts/a_download_model.sh) + +## Download Data + +Next, we download the XTREME data. We also need to download the MNLI and SQuAD datasets as training data for XNLI, XQuAD and MLQA. + +See: [**Code snippet**](jiant/scripts/benchmark_postproc/subscripts/b_download_data.sh) + +## Tokenize and Cache Data + +Now, we preprocess our data into a tokenized cache. We need to do this across all languages for each XTREME task, as well as MNLI and SQuAD. Somewhat tediously (and this will come up again), different tasks have slightly different phases (train/val/test) available, so we have slightly different configurations for each. + +See: [**Code snippet**](jiant/scripts/benchmark_postproc/subscripts/c_tokenize_and_cache.sh) + +## Generate Run configs + +Now, we generate the run configurations for each of our XTREME tasks. Each of the 9 XTREME tasks will correspond to one run. It's worth noting here: + +* XNLI uses MNLI for training, XQuAD and MLQA use SQuAD v1.1, while PAWS-X, UDPOS, PANX and TyDiQA have their own English training sets. +* For these tasks, we will train on the training set, and then evaluate the validation set for all available languages. +* Bucc2018 and Tatoeba, the sentence retrieval tasks, are not trained, and only run in evaluation mode. +* We need to ensure that all tasks in a single run use the exact same output head. This is prepared for you in the `xtreme_runconfig_writer`. We recommend looking over the resulting run config file to verify how the run is set up. +* In theory, we could do XQuAD and MLQA in a single run, since they are both trained on SQuAD and evaluated zero-shot. For simplicity, we will treat them as separate runs. You can combine them into a single run config by modifying the runconfig file. + +See: [**Code snippet**](jiant/scripts/benchmark_postproc/subscripts/d_write_configs.sh) + +## Train/Run models + +Now, we can fine-tune XLM-R on each task (in the cases of Bucc2018 and Tatoeba, we just run evaluation). + +We put this in the format for a bash loop here, but we recommend running these commands in parallel, one job for each task, if you have a cluster available. + +See: [**Code snippet**](jiant/scripts/benchmark_postproc/subscripts/e_run_models.sh) diff --git a/guides/experiments/large_scale_experiments.md b/guides/experiments/large_scale_experiments.md new file mode 100644 index 000000000..81155f018 --- /dev/null +++ b/guides/experiments/large_scale_experiments.md @@ -0,0 +1,35 @@ +# Tips for Large-scale Experiments + +`jiant` was designed with large-scale transfer-learning experiments in mind. Here are some tips to manage and collect results from multiple experiments. + +### Aggregated results using `path_parse` + +One common format for running experiments is to run something like the following on SLURM: + +```bash +for TASK in mnli rte squad_v1; do + for MODEL in roberta-base bert-base-cased; do + export TASK=${TASK} + export MODEL=${MODEL} + export OUTPUT_PATH=/path/to/experiments/${MODEL}/${TASK} + sbatch my_run_script.sbatch + done +done +``` +where `my_run_script.sbatch` kicks off an experiment, and where the run is saved to the output path `/path/to/experiments/${MODEL}/${TASK}`. As seen in [my_experiment_and_me.md](./my_experiment_and_me.md), the results are stored in `val_metrics.json`. + +A quick was to pick up the results across the range of experiments is to run code like this: + +```python +import pandas as pd +import jiant.utils.python.io as io +import jiant.utils.path_parse as path_parse + +matches = path_parse.match_paths("/path/to/experiments/{model}/{task}/val_metrics.json") +for match in matches: + match["score"] = io.read_json(match["path"])[match["task"]]["major"] + del match["path"] +df = pd.DataFrame(matches).set_index(["model", "task"]) +``` + +This returns a nice table of the results for each run across your range of experiments. diff --git a/guides/experiments/my_experiment_and_me.md b/guides/experiments/my_experiment_and_me.md new file mode 100644 index 000000000..d26060960 --- /dev/null +++ b/guides/experiments/my_experiment_and_me.md @@ -0,0 +1,15 @@ +# My Experiment and Me + +### Run outputs + +After running an experiment, you will see your run folder populated with many files and folders. Here's a quick run-down of what they are: + +* `args.json`: Saved a copy of your run arguments for future reference. +* `model.p`: Model weights at the end of training. +* `best_model.p`: The best version of the model weights based on validation-subset, +* `best_model.metadata.json`: Contains the metadata for the best-model-weights (e.g. what step of training they were from). +* `checkpoint.p`: A checkpoint for the run that allows you to resume interrupted runs. Contains additional training state, such as the optimizer state, so it's at least 2x as large as model weights. +* `{log-timestamp}/loss_train.zlog`: JSONL log of training loss over training steps +* `{log-timestamp}/early_stopping.zlog`: JSONL log of early-stopping progress (e.g. steps since last best model) +* `{log-timestamp}/train_val.zlog`: JSONL log of validation-subset evaluation over the course of training (i.e. what's used for early stopping) +* `{log-timestamp}/train_val_best.zlog`: JSONL log of validation-subset evaluation, only recording the improving runs diff --git a/guides/experiments/quick_start_cli.md b/guides/experiments/quick_start_cli.md new file mode 100644 index 000000000..6b1bb9d6c --- /dev/null +++ b/guides/experiments/quick_start_cli.md @@ -0,0 +1,35 @@ +# Quick Start Guide — Using the command line interface +In this tutorial we'll show you how to do a basic multitask training experiment using `jiant`'s command line interface. This tutorial requires your machine to have a GPU supporting CUDA. +If you haven't already installed `jiant`, clone it and install its dependencies: +``` +git clone https://github.com/jiant-dev/jiant.git +pip install -r jiant/requirements.txt +``` +For this multitask training example we'll use MRPC and RTE tasks from GLUE, so we'll need to prepare the task data first: +1. We'll get the data using Hugging Face's `download_glue_data.py` script: +``` +wget https://raw.githubusercontent.com/huggingface/transformers/master/utils/download_glue_data.py +python download_glue_data.py \ + --data_dir ./raw_data \ + --tasks "MRPC,RTE" +``` +2. We'll extract the data using `jiant`'s `export_glue_data.py` script: +``` +export PYTHONPATH=jiant/ +python jiant/jiant/scripts/preproc/export_glue_data.py \ + --input_base_path=./raw_data \ + --output_base_path=./tasks/ \ + --task_name_ls "mrpc,rte" +``` +Now that the data is ready, we can use `jiant`'s simple CLI to perform multitask training with a single command: +``` +python jiant/jiant/proj/simple/runscript.py \ + run \ + --run_name test_run \ + --exp_dir ./experiments/multi_task_mrpc_rte \ + --data_dir $(pwd)/tasks/data \ + --model_type bert-base-uncased \ + --train_batch_size 16 \ + --tasks mrpc,rte +``` +This simple experiment showed that you've installed `jiant` and can run a basic multitask experiment. For more advanced experimental workflows see the example notebooks [here](../notebooks). \ No newline at end of file diff --git a/guides/general/in_depth_into.md b/guides/general/in_depth_into.md new file mode 100644 index 000000000..9d886c3e5 --- /dev/null +++ b/guides/general/in_depth_into.md @@ -0,0 +1,104 @@ +# An In-Depth Introduction to `jiant` + +![jiant Pipeline](./pipeline_simplified.png "jiant Pipeline") + +This document provides an in-depth introduction to `jiant`. If you intend to use `jiant` for research and extend its functionality, e.g. adding a task, adding a model, or doing something much more novel (e.g. adding data augmentation, modifying the training pipeline, adversarial training), this is an excellent place to start. + +* [`jiant`'s models](#jiants-models) +* [`jiant`'s tasks](#jiants-tasks) +* [`Runner`s and `Metarunner`s](#runners-and-metarunners) +* [Step-by-step through `jiant`'s pipeline](#step-by-step-through-jiants-pipeline) + +## `jiant`'s models + +`jiant` is designed from the ground up to support multi-task training. As such, most models consist of an **encoder** e.g. BERT, and task-specific heads, such as 3-class classifiation for MNLI, span-prediction for SQuAD, and so on. The original pretraining head for the encoder (e.g. BERT's MLM head) is also often available. + +During training, the main model you will interact with is a `JiantModel` (see: [Source](../../jiant/proj/main/modeling/primary.py)). The `JiantModel`'s `.forward()` method takes as input a batch object and the task - the task tells the model which head to use. + +**Important**: Somewhat different from many single-encoder-multiple-head architectures, we expose the multiple heads not as different modules within `JiantModel`. Instead, `JiantModel` contains a dictionary to different `Taskmodels` (see: [Source](../../jiant/proj/main/modeling/taskmodels.py)). Each `Taskmodel` contains an encoder and corresponding task-specific head for the task. Each `Taskmodel`'s encoder is the same encoder as the encoder in the `JiantModel` - this is how we effectively share encoders across all our different tasks. The specific reason for this setup is a little nuanced, but it should not impact the regular usage of `jiant`. The important part of all this is that the `Taskmodel` both contains the task-specific head, and the `.forward()` method contains the logic for doing a forward pass on that task. For instance, the `MLMModel` does the random masking during `.forward()`, and the `MultipleChoiceModel` uses the encoder multiple times for a single example (each choice needs to be encoded). The `Taskmodel` also contains the logic for computing the loss for a given task format. + +To support different formats of multi-task training, `JiantModel`s can be flexibly configured to have different tasks use the same `Taskmodel` (or task "head"). For instance, you can train on multiple QA tasks, all using the same head. Alternatively for ANLI, you can train on MNLI, SNLI, and ANLI 1-3 all using the same NLI head. These can be configured via the `task_to_taskmodel_map`. + +**Summary** + +* A `JiantModel` consist of an **encoder** and one or more **task heads**. +* In practice, this is implemented by the `JiantModel` having one or more `Taskmodels`, all of which share the same encoder, and each having a task-specific output modules (i.e. "heads"). +* Users can map multiple tasks to use the same `Taskmodel`. + +## `jiant`'s tasks + +A "task" is a surprisingly hard to define concept (Is it a dataset? A format like question answering? Can the same "task" be evaluated in different ways?). + +In `jiant`, we think of the task as needing the following: + +1. Ability to read in data from some raw format +2. Ability to transform raw data input batches (consisting of arrays or tensors) +3. Evaluation scheme for `Taskmodel` outputs + +In other words, we need to process task data, and score model outputs. (Note from [the above](#jiants-models) that the loss computation is tied to the `Taskmodel`. The choice of `Taskmodel` is in turn tied to the task.) + +### Task preprocessing + +The task preprocessing pipeline is define in the task object. For instance, let's look at the `MnliTask` (see: [Source](../../jiant/tasks/lib/mnli.py)). You'll notice several dataclass-like definitions, and finally the `MnliTask` object at the bottom. Our preprocessing works by converting data through a series of processing steps, from raw `Example`s all the way to `DataRow`. Let's go through each step. + +1. Raw data → `Example`: The Task object defines how to read in examples from a raw text-based format (often `.jsonl`), and returns a list or iterable of `Example`. `Example`s contain the information we need to ultimately form batches. +2. `Example` → `TokenizedExample`: The `Example` class defines how to go from `Example`s to `TokenizedExample`s. This handles the tokenization of inputs, as well as any tokenization-related processing (e.g. mapping of span indices). +3. `TokenizedExample` → `DataRow`: The `TokenizedExample` class defines how to go from `TokenizedExample`s to `DataRow`s. `DataRow` contain the arrays (e.g. input IDs, input masks) that will ultimately be used to form the batches to be consumed by the `Taskmodel`'s forward method. This is where we handle all the input formatting, such as adding special tokens like `[ClS]` or ``, padding, and concatenating inputs (e.g. concatenating premise and hypothesis, for MNLI). +4. `DataRow` -> `Batch`: The conversion of `DataRow`s (which consist of NumPy Arrays) to `Batch`es (which consist of PyTorch Tensors) actually happens during the data loading stage. For those more familiar with PyTorch, we handle this via a custom `collate_fn` in `Task.collate_fn` (see: [Source](../../jiant/tasks/core.py)). + +Hence, when implementing a task, steps 1-3 need to be implemented, as well as class definition for each of the mentioned data structures: `Task`, `Example`, `TokenizedExample`, `DataRow` and `Batch`. See [Adding Tasks](../tasks/adding_tasks.md) for more details. Steps 1-3 happen in our "Tokenize & Cache" phase, while step 4 happens only during training. + +*Note*: A small number of tasks (e.g. any SQuAD variant) have a unique mapping from one `Example` to multiple `DataRow`s. + +### Evaluation Schemes + +(Evaluation of tasks can be slightly complicated. For simple metrics like accuracy, it is possible to compute some result for each example independently, and then combine them at the end to get the final score. For certain metrics, however, all predictions need to be evaluated together. On the other hand, you have some tasks where it is infeasible to store all predictions in memory. Because of these reasons, our Evaluation Schemes are a little complicated.) + +Each task is mapped to an `EvaluationScheme`, which take model predictions and batch data, and outputs a `Metrics` object. + +The `Metrics` object contains the relevant metrics for a given task, and has two important attributes: `major`, which is a scalar, and `minor`. `major` is a single-scalar summary of task performance and is used by the `Metarunner` for early stopping. `minor` is a dictionary that contains all relevant metrics for a task. For instance, many tasks have both `F1` and `EM` metrics, so we would record `F1` and `EM` in the `minor`, and report the average of both in the `major`. + +`EvaluationScheme`s themselves are a little complex to explain. During training or evaluation, `EvaluationScheme`s can generate an `Accumulator` object, which records the relevant information for computing the `Metrics` we want at the end. In most cases, this is simply the prediction, but some tasks require more information to be recorded at each training/evaluation step. After we are done with all the training/evaluation data, the `EvaluationScheme` takes the `Accumulator` and outputs the `Metrics` object. + +*Note*: The evaluation code for each task is currently all located in a single file (see: [Source](../../jiant/tasks/evaluate/core.py)) and we will likely move them to individual task implementations soon. + +**Summary** + +* Tasks need to define how to read and process task data, and score model outputs +* Tasks need to define a preprocessing pipeline, going from raw data → `Example` → `TokenizedExample` → `DataRow` -> `Batch`. `Batch`es get consumed by `Taskmodel`s. +* Tasks also need to be mapped to `EvaluationScheme`, which define how a task is scored. `EvaluationScheme`s collect gather information via `Accumulator`s during the training/validation phase, and output `Metrics`. + +## Runners and Metarunners + +For a given experiment, `Runner`s and `Metarunner`s handle our training and evaluation loops. Why do we have two different objects? We differentiate the responsibilities as follows: + +* `Runner`s handle all the logic that's needed to run a training step for a `JiantModel`. This includes everything from setting up data loaders, to sampling tasks, to computing losses and updating the weights. +* `Metarunner`s handle all the training-flow logic, such as early stopping, checkpointing, saving/loading the best models. + +If you are trying to experiment on a new modeling method, you are likely to want to subclass the `Runner` rather than the `Metarunner`. For instance, if you want to do some additional regularization based on entropy of the predictions, you would modify the `Runner`'s `training_step`. + +## Step-by-step through `jiant`'s pipeline + +![jiant Pipeline with code](./pipeline_scripts.svg "jiant Pipeline with code") + +This is the full end-to-end pipeline for a simple experiment in `jiant`. We include examples of the corresponding bash commands for each one. + +Let's assume we are fine-tuning RoBERTa on MRPC. This sounds simple, so why does it require so many steps? The design philosophy behind `jiant` is that we want to support research workflows, and that means exposing as much of the internals to users as possible, for allow for maximal inspectability and tweaking. Some of these steps are combined or hidden when using other libraries, but they should all be largely intuitive. + +### Downloading Task Data and Model + +First, we need to get our task data. `jiant` provides a data download script (see: [Source](../../jiant/scripts/download_data/runscript.py)), and saves both the downloaded data as well as task-config JSONs (containing paths to the downloaded data). (**Pro-tip**: Task-config allow you to point to different training/validation sets as needed. A common use-case is training on subsets or modified version of the training data.) + +Next, we download our models. These largely wrap around the `.from_pretrained` methods from `Transformers` and saves the relevant model config JSONs, weights, and tokenizer files to disk. + +### Tokenize & Cache + +As described in [`jiant`'s Tasks](#jiants-tasks), we preprocess our task data from raw files to `DataRow`s and then save them to disk. We refer to this as the task cache. The cache is saved in chunks of 10,000 examples to avoid OOM issues for tasks with many examples. + +### Write Run Config + +We write a run-configuration JSON that configures many parts of our training setup, including what tasks to train and/or evaluate on, number of steps, task-sampling strategy, batch sizes, gradient accumulation steps, and so on. The script provided (see: [Source](../../jiant/proj/main/scripts/configurator.py)) helps to write the most common run-configuration formats. In this case, we're using the `SimpleAPIMultiTaskConfigurator`. However, more complex workflows can be configured by manually modifying/generating the JSON files. For instance, for zero-shot transfer on XNLI in the XTREME benchmark, we need to configure a model to train on MNLI, evaluate on XNLI in 15 languages (those are 15 different tasks), and all tasks share the same NLI model. These can all be defined in the run-configuration. + +### Train & Evaluate + +Finally, we can run our train/evaluation script, which takes some training/evaluation-specific arguments, and paths to some of our above outputs. At the end, you will obtain model weights, validation scores, and/or predictions, depending on your options. For more, see: [My Experiment and Me](../experiments/my_experiment_and_me.md). diff --git a/guides/general/pipeline_scripts.png b/guides/general/pipeline_scripts.png new file mode 100644 index 000000000..5db931f81 Binary files /dev/null and b/guides/general/pipeline_scripts.png differ diff --git a/guides/general/pipeline_scripts.svg b/guides/general/pipeline_scripts.svg new file mode 100644 index 000000000..0b774b89c --- /dev/null +++ b/guides/general/pipeline_scripts.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/guides/general/pipeline_simplified.png b/guides/general/pipeline_simplified.png new file mode 100644 index 000000000..3b20bd5ae Binary files /dev/null and b/guides/general/pipeline_simplified.png differ diff --git a/guides/tasks/adding_tasks.md b/guides/tasks/adding_tasks.md new file mode 100644 index 000000000..c8bc560f8 --- /dev/null +++ b/guides/tasks/adding_tasks.md @@ -0,0 +1,181 @@ +# Adding a Task + +In this tutorial we’ll show you how to add a new task to `jiant`. + +We’ll use a real task for this example: Senteval’s Tense task. Senteval’s tense task is a single sentence classification task with labels “PAST” or “PRES”, and it uses accuracy as its evaluation metric. + +Adding Senteval’s Tense task will require touching three files: +1. A (new) task file: `jiant/tasks/lib/senteval/tense.py` +2. The task retrieval library: `jiant/tasks/retrieval.py` +3. The evaluation library: `jiant/tasks/evaluate/core.py` + +We’ll talk about these files in the following sections. + +## 1. The Task file + +Tasks files have 5 core components: + +1. `Task` class +2. `Example` dataclass +3. `TokenizedExample` dataclass +4. `DataRow` dataclass +5. `Batch` dataclass + +In the following sections we’ll explain these components (and build up a working example in code blocks). + +#### 1. `Task` class + +`Task` classes have attributes describing the task, and methods for producing `Example`s. +1. Attributes: + 1. `TASK_TYPE`: This attribute tells the model setup process what type of head the task requires. For our task the type is `CLASSIFICATION`. + 2. `LABELS` are used for mapping the label in the inputs files to input IDs. +2. `Example` getter methods instantiate and return `Examples`. When `jiant`’s core code calls the `get_train_examples()` method, this method must return an iterable of task `Example`s. + +Here's an example of how we can define a `SentevalTenseTask` class: +```python +class SentevalTenseTask(Task): + TASK_TYPE = TaskTypes.CLASSIFICATION + + LABELS = ["PAST", "PRES"] + LABEL_TO_ID, ID_TO_LABEL = labels_to_bimap(LABELS) + + def get_train_examples(self): + return self._create_examples(path=self.train_path, set_type="train") + + def get_val_examples(self): + return self._create_examples(path=self.val_path, set_type="val") + + def get_test_examples(self): + return self._create_examples(path=self.test_path, set_type="test") + + @classmethod + def _create_examples(cls, path, set_type): + examples = [] + df = pd.read_csv(path, index_col=0, names=["split", "label", "text", "unk_1", "unk_2"]) + for i, row in df.iterrows(): + examples.append( + Example( + guid="%s-%s" % (set_type, i), + text=row.text, + label=row.label if set_type != "test" else cls.LABELS[-1], + ) + ) + return examples +``` + +#### 2. `Example` dataclass +This dataclass must implement a `tokenize()` method. The `tokenize()` method is expected to take a tokenizer as an argument, use the tokenizer to tokenize the input text, translate label strings into label IDs, and create and return a `TokenizedExample`. + +```python +@dataclass +class Example(BaseExample): + guid: str + text: str + label: str + + def tokenize(self, tokenizer): + return TokenizedExample( + guid=self.guid, + text=tokenizer.tokenize(self.text), + label_id=SentevalTenseTask.LABEL_TO_ID[self.label], + ) +``` + +#### 3. `TokenizedExample` dataclass + +The `TokenizedExample` dataclass must implement a `featurize()` method that takes a `Tokenizer` and `FeaturizationSpec`. It must return the example as a `DataRow` (including input IDs, input mask, and label ID and applying any model specific max sequence length and special tokens). The resulting `DataRow` can also optionally include metadata (e.g., guid and tokens) as well. + +Note: the task we’re implementing has a common format (single-sentence classification) and we can use the `single_sentence_featurize()` function to form `DataRow` which has all the components expected by a Transformer model. For tasks with unusual featurization requirements, the featurize method can be home to additional featurization logic. + +```python +@dataclass +class TokenizedExample(BaseTokenizedExample): + guid: str + text: List + label_id: int + + def featurize(self, tokenizer, feat_spec): + return single_sentence_featurize( + guid=self.guid, + input_tokens=self.text, + label_id=self.label_id, + tokenizer=tokenizer, + feat_spec=feat_spec, + data_row_class=DataRow, + ) +``` + +#### 4. `DataRow` dataclass +This dataclass’ fields contain the data that will be passed to the model after batching. + +```python +@dataclass +class DataRow(BaseDataRow): + guid: str + input_ids: np.ndarray + input_mask: np.ndarray + segment_ids: np.ndarray + label_id: int + tokens: list +``` + +#### 5. `Batch` dataclass +This dataclass will contain examples batched for consumption by the model. Type annotations are used to cast the numpy data structures to the appropriate Torch Tensor type. + +```python +@dataclass +class Batch(BatchMixin): + input_ids: torch.LongTensor + input_mask: torch.LongTensor + segment_ids: torch.LongTensor + label_id: torch.LongTensor + tokens: list +``` + +Now that we've implemented required components of our SentevalTenseTask, we're ready to add it to the task retrieval library. + +## 2. Task retrieval library +To register your task with the task retrieval library (in [`jiant/tasks/retrieval.py`](../../jiant/tasks/retrieval.py)) you simply associate your Task class with a short name in the `TASK_DICT`: + +```python +TASK_DICT = { +... + "senteval_tense": SentevalTenseTask, + ... +} + +``` + +## 3. Evaluation library +Your task will need an evaluation scheme. Task evaluation schemes are specified in [`jiant/tasks/evaluate/core.py`](../../jiant/tasks/evaluate/core.py). Many common evaluation schemes are defined in this file. As a reminder, the `SentevalTenseTask` we’re adding in this guide is a two-class classification task which is evaluated using accuracy, so we’ll add it to the list of tasks that use the `SimpleAccuracyEvaluationScheme`: + +```python +def get_evaluation_scheme_for_task(task) -> BaseEvaluationScheme: + if isinstance( + task, + ( + # ... + tasks.SentevalTenseTask, + # ... + ), + ): + return SimpleAccuracyEvaluationScheme() +``` + +And that’s it. You’ve made all the core code changes required to include the `SentevalTenseTask` in your `jiant` experiments. + +What's next? To tokenize and cache your `SentevalTenseTask` (which you shortnamed `senteval_tense`) for an experiement, you'll need to provide a task config `json` file pointing to your task's data: + +```json +{ + "task": "senteval_tense", + "paths": { + "train": "/data/Senteval/past_present/train.csv", + "val": "/data/Senteval/past_present/val.csv", + "test": "/data/Senteval/past_present/test.csv" + }, + "name": "senteval_tense" +} +``` + +To learn more about running experiments with you new task, check out the examples [available here](../README.md). \ No newline at end of file diff --git a/guides/tasks/supported_tasks.md b/guides/tasks/supported_tasks.md new file mode 100644 index 000000000..80e0bc1e0 --- /dev/null +++ b/guides/tasks/supported_tasks.md @@ -0,0 +1,67 @@ +# Tasks + +## Supported Tasks + +| Name | `task_name` | `jiant` | Downloader | `jiant_task_name` | Misc | +|---|---|:---:|:---:|---|---| +| Abductive NLI | abductive_nli | ✅ | ✅ | abductive_nli | | +| SuperGLUE Winogender Diagnostic | superglue_axg | ✅ | ✅ | superglue_axg | SuperGLUE | +| Acceptability Definiteness | acceptability_definiteness | ✅ | | acceptability_definiteness | Function Words | +| Adversarial NLI | `adversarial_nli_{round}` | ✅ | | adversarial_nli | 3 rounds | +| BoolQ | boolq | ✅ | ✅ | boolq | SuperGLUE | +| BUCC2018 | `bucc2018_{lang}` | ✅ | ✅ | bucc2018 | XTREME, multi-lang | +| CommitmentBank | cb | ✅ | ✅ | cb | SuperGLUE | +| CCG | ccg | ✅ | | ccg | | +| CoLA | cola | ✅ | ✅ | cola | GLUE | +| CommonsenseQA | commonsenseqa | ✅ | ✅ | commonsenseqa | | +| EP-Const | nonterminal | ✅ | | nonterminal | Edge-Probing | +| COPA | copa | ✅ | ✅ | copa | SuperGLUE | +| EP-Coref | coref | ✅ | | coref | Edge-Probing | +| Cosmos QA | cosmosqa | ✅ | ✅ | cosmosqa | | +| EP-UD | dep | ✅ | | dep | Edge-Probing | +| EP-DPR | dpr | ✅ | | dpr | Edge-Probing | +| GLUE Diagnostic | glue_diagnostics | ✅ | ✅ | glue_diagnostics | GLUE | +| HellaSwag | hellaswag | ✅ | ✅ | hellaswag | | +| MLM | * | ✅ | * | mlm_simple | See task-specific notes. | +| MLQA | `mlqa_{lang1}_{lang2}` | ✅ | ✅ | mlqa | XTREME, multi-lang | +| MNLI | mnli | ✅ | ✅ | mnli | GLUE, MNLI-matched | +| MNLI-mismatched | mnli_mismatched | ✅ | ✅ | mnli_mismatched | GLUE | +| MultiRC | multirc | ✅ | ✅ | multirc | SuperGLUE | +| MRPC | mrpc | ✅ | ✅ | mrpc | GLUE | +| QAMR | qamr | ✅ | ✅ | qamr | | +| QA-SRL | qa-srl | ✅ | ✅ | qa-srl | | +| EP-NER | ner | ✅ | | ner | Edge-Probing | +| PAWS-X | `pawsx_{lang}` | ✅ | ✅ | pawsx | XTREME, multi-lang | +| WikiAnn | `panx_{lang}` | ✅ | ✅ | panx | XTREME, multi-lang | +| EP-POS | pos | ✅ | | pos | Edge-Probing | +| QNLI | qnli | ✅ | ✅ | qnli | GLUE | +| QQP | qqp | ✅ | ✅ | qqp | GLUE | +| ReCord | record | ✅ | ✅ | record | SuperGLUE | +| RTE | rte | ✅ | ✅ | rte | GLUE, SuperGLUE | +| SciTail | scitail | ✅ | ✅ | scitail | | +| SentEval: Tense | senteval_tense | ✅ | | senteval_tense | SentEval | +| EP-Rel | semeval | ✅ | | semeval | Edge-Probing | +| SNLI | snli | ✅ | ✅ | snli | | +| SocialIQA | socialiqa | ✅ | ✅ | socialiqa | | +| EP-SPR1 | spr1 | ✅ | | spr1 | Edge-Probing | +| EP-SPR2 | spr2 | ✅ | | spr2 | Edge-Probing | +| SQuAD 1.1 | squad_v1 | ✅ | ✅ | squad | | +| SQuAD 2.0 | squad_v2 | ✅ | ✅ | squad | | +| EP-SRL | srl | ✅ | | srl | Edge-Probing | +| SST-2 | sst | ✅ | ✅ | sst | GLUE | +| STS-B | stsb | ✅ | ✅ | stsb | GLUE | +| SuperGLUE Broad Coverage Diagnostic | superglue_axg | ✅ | ✅ | superglue_axg | SuperGLUE | +| SWAG | swag | ✅ | ✅ | swag | | +| Tatoeba | `tatoeba_{lang}` | ✅ | ✅ | tatoeba | XTREME, multi-lang | +| TyDiQA | `tydiqa_{lang}` | ✅ | ✅ | tydiqa | XTREME, multi-lang | +| UDPOS | `udpos_{lang}` | ✅ | ✅ | udpos | XTREME, multi-lang | +| WiC | wic | ✅ | ✅ | wic | SuperGLUE | +| WNLI | wnli | ✅ | ✅ | wnli | GLUE | +| WSC | wsc | ✅ | ✅ | wsc | SuperGLUE | +| XNLI | `xnli_{lang}` | ✅ | ✅ | xnli | XTREME, multi-lang | +| XQuAD | `xquad_{lang}` | ✅ | ✅ | xquad | XTREME, multi-lang | + +* `task_name`: Name-by-convention, used by downloader, and used in `JiantModel` to map from task names to task-models. You can change this as long as your settings are internally consistent. +* `jiant`: Whether it's supported in `jiant` (i.e. you can train/eval on it) +* Downloader: Whether you can download using the downloader. +* `jiant_task_name`: Used to determine the programmatic behavior for the task (how to tokenize, what *kind* of task-model is compatible). Is tied directly to the code. See: `jiant.tasks.retrieval`. diff --git a/guides/tasks/task_specific.md b/guides/tasks/task_specific.md new file mode 100644 index 000000000..d28d63915 --- /dev/null +++ b/guides/tasks/task_specific.md @@ -0,0 +1,64 @@ +## Task-specific Notes + +### Adversarial NLI + +[Adversarial NLI](https://arxiv.org/pdf/1910.14599.pdf) has 3 rounds of adversarial data creation. A1/A2/A3 are expanding supersets of the previous round. + + +### Masked Language Modeling (MLM) + +MLM is a generic task, implemented with the `jiant_task_name` "`mlm_simple`". In other words, it is meant to be used with any appropriately formatted file. + +`mlm_simple` expects input data files to be a single text file per phase, where each line corresponds to one example, and empty lines are ignored. This means that if a line corresponds to more than the `max_seq_length` of tokens during tokenization, everything past the first `max_seq_length` tokens per line will be ignored. We plan to add more complex implementations in the future. + +You can structure your MLM task config file as follow: + +```json +{ + "task": "mlm_simple", + "paths": { + "train": "/path/to/train.txt", + "val": "/path/to/val.txt" + }, + "name": "my_mlm_task" +} +``` + +### UDPOS (XTREME) + +UDPOS requires a specific version `networkx` to download. You can install it via + +```bash +pip install networkx==1.11 +``` + + +### PAN-X (XTREME) + +To preprocess PAN-X, you actually first need to download the file from: https://www.amazon.com/clouddrive/share/d3KGCRCIYwhKJF0H3eWA26hjg2ZCRhjpEQtDL70FSBN. + +The file should be named `AmazonPhotos.zip`, and it should be placed in `${task_data_base_path}/panx_temp/AmazonPhotos.zip` before running the download script. + + +### Bucc2018, Tatoeba (XTREME) + +The Bucc2018 and Tatoeba tasks are sentence retrieval tasks, and require the `faiss` library to run. `faiss-gpu` is recommended for speed reasons. + +We recommend running: + +```bash +conda install faiss-gpu cudatoolkit=10.1 -c pytorch +``` + +(Use the appropriate `cudatoolkit` version, which you can check with `nvcc --version`.) + +Additionally, the task-model corresponding to retrieval tasks outputs an pooled embedding from a given layer of the encoder. As such, both the layer and pooling method need to be specified in taskmodel config. For instance, to replicate the baseline used in the XTREME benchmark, consider using: + +```python +{ + "pooler_type": "mean", + "layer": 14, +} +``` + +Also note that neither task has training sets, and Tatoeba does not have a separate test set. \ No newline at end of file diff --git a/jiant/__main__.py b/jiant/__main__.py deleted file mode 100644 index c7a7cd87e..000000000 --- a/jiant/__main__.py +++ /dev/null @@ -1,703 +0,0 @@ -"""Main flow for jiant. - -To debug this, run with -m ipdb: - - ipdb3 jiant/__main__.py --config_file ... -""" -# pylint: disable=no-member -import logging as log -from typing import Iterable - -log.basicConfig( - format="%(asctime)s: %(message)s", datefmt="%m/%d %I:%M:%S %p", level=log.INFO -) # noqa -import argparse -import glob -import io -import os -from pkg_resources import resource_filename -import random -import subprocess -import sys -import time -import copy -import torch -import torch.nn as nn - -from jiant import evaluate -from jiant.models import build_model -from jiant.preprocess import build_tasks -from jiant import tasks as task_modules -from jiant.trainer import build_trainer -from jiant.utils import config, tokenizers -from jiant.utils.options import parse_cuda_list_arg -from jiant.utils.utils import ( - assert_for_log, - load_model_state, - maybe_make_dir, - parse_json_diff, - sort_param_recursive, - select_relevant_print_args, - check_for_previous_checkpoints, - select_pool_type, - delete_all_checkpoints, - get_model_attribute, - uses_cuda, -) - - -# Global notification handler, can be accessed outside main() during exception handling. -EMAIL_NOTIFIER = None - - -def handle_arguments(cl_arguments: Iterable[str]) -> argparse.Namespace: - """Defines jiant's CLI argument parsing logic - - Parameters - ---------- - cl_arguments : Iterable[str] - An sys.argv-style args obj. - - Returns - ------- - argparse.Namespace - A map of params and parsed args - """ - parser = argparse.ArgumentParser(description="") - # Configuration files - parser.add_argument( - "--config_file", - "-c", - type=str, - nargs="+", - default=resource_filename("jiant", "config/defaults.conf"), - help="Config file(s) (.conf) for model parameters.", - ) - parser.add_argument( - "--overrides", - "-o", - type=str, - default=None, - help="Parameter overrides, as valid HOCON string.", - ) - - parser.add_argument( - "--remote_log", "-r", action="store_true", help="If true, enable remote logging on GCP." - ) - - parser.add_argument( - "--notify", type=str, default="", help="Email address for job notifications." - ) - - parser.add_argument( - "--tensorboard", - "-t", - action="store_true", - help="If true, will run Tensorboard server in a " - "subprocess, serving on the port given by " - "--tensorboard_port.", - ) - parser.add_argument("--tensorboard_port", type=int, default=6006) - - return parser.parse_args(cl_arguments) - - -def setup_target_task_training(args, target_tasks, model, strict): - """ - Gets the model path used to restore model after each target - task run, and saves current state if no other previous checkpoint can - be used as the model path. - The logic for loading the correct model state for target task training is: - 1) If load_target_train_checkpoint is used, then load the weights from that checkpoint. - 2) If we did pretraining, then load the best model from pretraining. - 3) Default case: we save untrained encoder weights. - - Parameters - ---------------- - args: Params object - target_tasks: list of target Task objects - mdoel: a MultiTaskModel object - - Returns - ---------------- - model_path: str - """ - model_path = get_best_checkpoint_path(args, "target_train") - if model_path is None: - # We want to do target training without pretraining, thus - # we need to first create a checkpoint to come back to for each of - # the target tasks to finetune. - if args.transfer_paradigm == "frozen": - assert_for_log( - args.allow_untrained_encoder_parameters, - "No best checkpoint found to target train on. Set \ - `allow_untrained_encoder_parameters` if you really want to use an untrained \ - encoder.", - ) - model_path = os.path.join(args.run_dir, "model_state_untrained_pre_target_train.th") - torch.save(model.state_dict(), model_path) - - return model_path - - -def check_configurations(args, pretrain_tasks, target_tasks): - """ - Checks configurations for any obvious logical flaws - and that necessary parameters are set for each step - - throws asserts and exits if found. - - Parameters - ---------------- - args: Params object - pretrain_tasks: list of pretraining Task objects - target_tasks: list of target task training Task objects - - Returns - ---------------- - None - """ - steps_log = io.StringIO() - if any([t.val_metric_decreases for t in pretrain_tasks]) and any( - [not t.val_metric_decreases for t in pretrain_tasks] - ): - log.warn("\tMixing training tasks with increasing and decreasing val metrics!") - - assert ( - hasattr(args, "accumulation_steps") and args.accumulation_steps >= 1 - ), "accumulation_steps must be a positive int." - - if args.load_target_train_checkpoint != "none": - assert_for_log( - not args.do_pretrain, - "Error: Attempting to train a model and then replace that model with one from " - "a checkpoint.", - ) - steps_log.write("Loading model from path: %s \n" % args.load_target_train_checkpoint) - - assert_for_log( - args.transfer_paradigm in ["finetune", "frozen"], - "Transfer paradigm %s not supported!" % args.transfer_paradigm, - ) - - if args.do_pretrain: - assert_for_log( - args.pretrain_tasks not in ("none", "", None), - "Error: Must specify at least one pretraining task: [%s]" % args.pretrain_tasks, - ) - steps_log.write("Training model on tasks: %s \n" % args.pretrain_tasks) - - if args.do_target_task_training: - assert_for_log( - args.target_tasks not in ("none", "", None), - "Error: Must specify at least one target task: [%s]" % args.target_tasks, - ) - steps_log.write("Re-training model for individual target tasks \n") - assert_for_log( - len(set(pretrain_tasks).intersection(target_tasks)) == 0 - or args.allow_reuse_of_pretraining_parameters - or args.do_pretrain == 0, - "If you're pretraining on a task you plan to reuse as a target task, set\n" - "allow_reuse_of_pretraining_parameters = 1 (risky), or train in two steps:\n" - "train with do_pretrain = 1, do_target_task_training = 0, stop, and restart with\n" - "do_pretrain = 0 and do_target_task_training = 1.", - ) - if args.do_full_eval: - assert_for_log( - args.target_tasks != "none", - "Error: Must specify at least one target task: [%s]" % args.target_tasks, - ) - if not args.do_target_task_training: - untrained_tasks = set( - config.get_task_attr(args, task.name, "use_classifier", default=task.name) - for task in target_tasks - ) - if args.do_pretrain: - untrained_tasks -= set( - config.get_task_attr(args, task.name, "use_classifier", default=task.name) - for task in pretrain_tasks - ) - if len(untrained_tasks) > 0: - assert ( - args.load_model - or args.load_target_train_checkpoint not in ["none", ""] - or args.allow_untrained_encoder_parameters - ), f"Evaluating a target task model on tasks {untrained_tasks} " - "without training it on this run or loading a checkpoint. " - "Set `allow_untrained_encoder_parameters` if you really want to use " - "an untrained task model." - log.warning( - f"Evauluating a target task model on tasks {untrained_tasks} without training " - "it in this run. It's up to you to ensure that you are loading parameters " - "that were sufficiently trained for this task." - ) - steps_log.write("Evaluating model on tasks: %s \n" % args.target_tasks) - - log.info("Will run the following steps for this experiment:\n%s", steps_log.getvalue()) - steps_log.close() - - -def _log_git_info(): - try: - # Make sure we run git in the directory that contains this file, even if the working - # directory is elsewhere. - main_dir = os.path.dirname(os.path.abspath(__file__)) - - # Use git to get branch/commit ID information. - c = subprocess.run( - ["git", "rev-parse", "--abbrev-ref", "HEAD"], - timeout=10, - stdout=subprocess.PIPE, - cwd=main_dir, - ) - git_branch_name = c.stdout.decode().strip() - log.info("Git branch: %s", git_branch_name) - c = subprocess.run( - ["git", "rev-parse", "HEAD"], timeout=10, stdout=subprocess.PIPE, cwd=main_dir - ) - git_sha = c.stdout.decode().strip() - log.info("Git SHA: %s", git_sha) - except subprocess.TimeoutExpired as e: - log.exception(e) - log.warn("Git info not found. Moving right along...") - - -def _run_background_tensorboard(logdir, port): - """Run a TensorBoard server in the background.""" - import atexit - - tb_args = ["tensorboard", "--logdir", logdir, "--port", str(port)] - log.info("Starting TensorBoard server on port %d ...", port) - tb_process = subprocess.Popen(tb_args) - log.info("TensorBoard process: %d", tb_process.pid) - - def _kill_tb_child(): - log.info("Shutting down TensorBoard server on port %d ...", port) - tb_process.terminate() - - atexit.register(_kill_tb_child) - - -def get_best_checkpoint_path(args, phase, task_name=None): - """ Look in run_dir for model checkpoint to load when setting up for - phase = target_train or phase = eval. - Hierarchy is: - If phase == target_train: - 1) user-specified target task checkpoint - 2) best task-specific checkpoint from pretraining stage - If phase == eval: - 1) user-specified eval checkpoint - 2) best task-specific checkpoint for target_train, used when evaluating - 3) best pretraining checkpoint - If all these fail, then we default to None. - """ - checkpoint = [] - if phase == "target_train": - if args.load_target_train_checkpoint not in ("none", ""): - checkpoint = glob.glob(args.load_target_train_checkpoint) - assert len(checkpoint) > 0, ( - "Specified load_target_train_checkpoint not found: %r" - % args.load_target_train_checkpoint - ) - else: - checkpoint = glob.glob(os.path.join(args.run_dir, "model_state_pretrain_val_*.best.th")) - if phase == "eval": - if args.load_eval_checkpoint not in ("none", ""): - checkpoint = glob.glob(args.load_eval_checkpoint) - assert len(checkpoint) > 0, ( - "Specified load_eval_checkpoint not found: %r" % args.load_eval_checkpoint - ) - else: - # Get the best checkpoint from the target_train phase to evaluate on. - assert task_name is not None, "Specify a task checkpoint to evaluate from." - checkpoint = glob.glob( - os.path.join(args.run_dir, task_name, "model_state_target_train_val_*.best.th") - ) - if len(checkpoint) == 0: - checkpoint = glob.glob( - os.path.join(args.run_dir, "model_state_pretrain_val_*.best.th") - ) - - if len(checkpoint) > 0: - assert_for_log(len(checkpoint) == 1, "Too many best checkpoints. Something is wrong.") - return checkpoint[0] - return None - - -def evaluate_and_write(args, model, tasks, splits_to_write, cuda_device): - """ Evaluate a model on dev and/or test, then write predictions """ - val_results, val_preds = evaluate.evaluate(model, tasks, args.batch_size, cuda_device, "val") - if "val" in splits_to_write: - evaluate.write_preds( - tasks, val_preds, args.run_dir, "val", strict_glue_format=args.write_strict_glue_format - ) - if "test" in splits_to_write: - _, te_preds = evaluate.evaluate(model, tasks, args.batch_size, cuda_device, "test") - evaluate.write_preds( - tasks, te_preds, args.run_dir, "test", strict_glue_format=args.write_strict_glue_format - ) - - run_name = args.get("run_name", os.path.basename(args.run_dir)) - results_tsv = os.path.join(args.exp_dir, "results.tsv") - log.info("Writing results for split 'val' to %s", results_tsv) - evaluate.write_results(val_results, results_tsv, run_name=run_name) - - -def initial_setup(args: config.Params, cl_args: argparse.Namespace) -> (config.Params, int): - """Perform setup steps: - - 1. create project, exp, and run dirs if they don't already exist - 2. create log formatter - 3. configure GCP remote logging - 4. set up email notifier - 5. log git info - 6. write the config out to file - 7. log diff between default and experiment's configs - 8. choose torch's and random's random seed - 9. if config specifies a single GPU, then set the GPU's random seed (doesn't cover multi-GPU) - 10. resolve "auto" settings for tokenizer and pool_type parameters - - Parameters - ---------- - args : config.Params - config map - cl_args : argparse.Namespace - mapping named arguments to parsed values - - Returns - ------- - args : config.Params - config map - seed : int - random's and pytorch's random seed - - """ - output = io.StringIO() - maybe_make_dir(args.project_dir) # e.g. /nfs/jsalt/exp/$HOSTNAME - maybe_make_dir(args.exp_dir) # e.g. /jiant-demo - maybe_make_dir(args.run_dir) # e.g. /jiant-demo/sst - log_fh = log.FileHandler(args.local_log_path) - log_fmt = log.Formatter("%(asctime)s: %(message)s", datefmt="%m/%d %I:%M:%S %p") - log_fh.setFormatter(log_fmt) - log.getLogger().addHandler(log_fh) - - if cl_args.remote_log: - from jiant.utils import gcp - - gcp.configure_remote_logging(args.remote_log_name) - - if cl_args.notify: - from jiant.utils import emails - - global EMAIL_NOTIFIER - log.info("Registering email notifier for %s", cl_args.notify) - EMAIL_NOTIFIER = emails.get_notifier(cl_args.notify, args) - - if EMAIL_NOTIFIER: - EMAIL_NOTIFIER(body="Starting run.", prefix="") - - _log_git_info() - config_file = os.path.join(args.run_dir, "params.conf") - config.write_params(args, config_file) - - print_args = select_relevant_print_args(args) - log.info("Parsed args: \n%s", print_args) - - log.info("Saved config to %s", config_file) - - seed = random.randint(1, 10000) if args.random_seed < 0 else args.random_seed - random.seed(seed) - torch.manual_seed(seed) - log.info("Using random seed %d", seed) - if isinstance(args.cuda, int) and args.cuda >= 0: - # If only running on one GPU. - try: - if not torch.cuda.is_available(): - raise EnvironmentError("CUDA is not available, or not detected" " by PyTorch.") - log.info("Using GPU %d", args.cuda) - torch.cuda.set_device(args.cuda) - torch.cuda.manual_seed_all(seed) - except Exception: - log.warning( - "GPU access failed. You might be using a CPU-only installation of PyTorch. " - "Falling back to CPU." - ) - args.cuda = -1 - - if args.tokenizer == "auto": - args.tokenizer = tokenizers.select_tokenizer(args) - if args.pool_type == "auto": - args.pool_type = select_pool_type(args) - - return args, seed - - -def check_arg_name(args: config.Params): - """Check for obsolete params in config, throw exceptions if obsolete params are found. - - Parameters - ---------- - args: config.Params - config map - - Raises - ------ - AssertionError - If obsolete parameter names are present in config - - """ - # Mapping - key: old name, value: new name - name_dict = { - "task_patience": "lr_patience", - "do_train": "do_pretrain", - "train_for_eval": "do_target_task_training", - "do_eval": "do_full_eval", - "train_tasks": "pretrain_tasks", - "eval_tasks": "target_tasks", - "eval_data_fraction": "target_train_data_fraction", - "eval_val_interval": "target_train_val_interval", - "eval_max_vals": "target_train_max_vals", - "eval_data_fraction": "target_train_data_fraction", - } - for task in task_modules.ALL_GLUE_TASKS + task_modules.ALL_SUPERGLUE_TASKS: - assert_for_log( - not args.regex_contains("^{}_".format(task)), - "Error: Attempting to load old task-specific args for task %s, please refer to the " - "master branch's default configs for the most recent task specific argument " - "structures." % task, - ) - for old_name, new_name in name_dict.items(): - assert_for_log( - old_name not in args, - "Error: Attempting to load old arg name %s, please update to new name %s." - % (old_name, name_dict[old_name]), - ) - old_input_module_vals = [ - "elmo", - "elmo_chars_only", - "bert_model_name", - "openai_transformer", - "word_embs", - ] - for input_type in old_input_module_vals: - assert_for_log( - input_type not in args, - "Error: Attempting to load old arg name %s, please use input_module config " - "parameter and refer to master branch's default configs for current way to specify %s." - % (input_type, input_type), - ) - - -def load_model_for_target_train_run(args, ckpt_path, model, strict, task, cuda_devices): - """ - Function that reloads model if necessary and extracts trainable parts - of the model in preparation for target_task training. - It only reloads model after the first task is trained. - - Parameters - ------------------- - args: config.Param object, - ckpt_path: str: path to reload model from, - model: MultiTaskModel object, - strict: bool, - task: Task object - - Returns - ------------------- - to_train: List of tuples of (name, weight) of trainable parameters - - """ - load_model_state(model, ckpt_path, cuda_devices, skip_task_models=[task.name], strict=strict) - if args.transfer_paradigm == "finetune": - # Train both the task specific models as well as sentence encoder. - to_train = [(n, p) for n, p in model.named_parameters() if p.requires_grad] - else: # args.transfer_paradigm == "frozen": - # will be empty if args.input_module != "elmo", scalar_mix_0 should always be - # pretrain scalars - elmo_scalars = [ - (n, p) - for n, p in model.named_parameters() - if "scalar_mix" in n and "scalar_mix_0" not in n - ] - # Fails when sep_embs_for_skip is 0 and elmo_scalars has nonzero - # length. - assert_for_log( - not elmo_scalars or args.sep_embs_for_skip, - "Error: ELMo scalars loaded and will be updated in do_target_task_training but " - "they should not be updated! Check sep_embs_for_skip flag or make an issue.", - ) - # Only train task-specific module - - pred_module = get_model_attribute(model, "%s_mdl" % task.name, cuda_devices) - to_train = [(n, p) for n, p in pred_module.named_parameters() if p.requires_grad] - to_train += elmo_scalars - model = model.cuda() if uses_cuda(cuda_devices) else model - if isinstance(cuda_devices, list): - model = nn.DataParallel(model, device_ids=cuda_devices) - return to_train - - -def get_pretrain_stop_metric(early_stopping_method, pretrain_tasks): - """ - Get stop_metric, which is used for early stopping. - - Parameters - ------------------- - early_stopping_method: str, - pretrain_tasks: List[Task] - - Returns - ------------------- - stop_metric: str - - """ - if early_stopping_method != "auto": - pretrain_names = [task.name for task in pretrain_tasks] - if early_stopping_method in pretrain_names: - index = pretrain_names.index(early_stopping_method) - stop_metric = pretrain_tasks[index].val_metric - else: - raise ValueError("args.early_stopping_method must be either 'auto' or a task name") - - else: - stop_metric = pretrain_tasks[0].val_metric if len(pretrain_tasks) == 1 else "macro_avg" - return stop_metric - - -def main(cl_arguments): - """ Train a model for multitask-training.""" - cl_args = handle_arguments(cl_arguments) - args = config.params_from_file(cl_args.config_file, cl_args.overrides) - # Check for deprecated arg names - check_arg_name(args) - args, seed = initial_setup(args, cl_args) - # Load tasks - log.info("Loading tasks...") - start_time = time.time() - cuda_device = parse_cuda_list_arg(args.cuda) - pretrain_tasks, target_tasks, vocab, word_embs = build_tasks(args, cuda_device) - tasks = sorted(set(pretrain_tasks + target_tasks), key=lambda x: x.name) - log.info("\tFinished loading tasks in %.3fs", time.time() - start_time) - log.info("\t Tasks: {}".format([task.name for task in tasks])) - # Build model - log.info("Building model...") - start_time = time.time() - model = build_model(args, vocab, word_embs, tasks, cuda_device) - log.info("Finished building model in %.3fs", time.time() - start_time) - - # Start Tensorboard if requested - if cl_args.tensorboard: - tb_logdir = os.path.join(args.run_dir, "tensorboard") - _run_background_tensorboard(tb_logdir, cl_args.tensorboard_port) - - check_configurations(args, pretrain_tasks, target_tasks) - if args.do_pretrain: - # Train on pretrain tasks - log.info("Training...") - stop_metric = get_pretrain_stop_metric(args.early_stopping_method, pretrain_tasks) - should_decrease = ( - pretrain_tasks[0].val_metric_decreases if len(pretrain_tasks) == 1 else False - ) - trainer, _, opt_params, schd_params = build_trainer( - args, cuda_device, [], model, args.run_dir, should_decrease, phase="pretrain" - ) - to_train = [(n, p) for n, p in model.named_parameters() if p.requires_grad] - _ = trainer.train( - pretrain_tasks, - stop_metric, - args.batch_size, - args.weighting_method, - args.scaling_method, - to_train, - opt_params, - schd_params, - args.load_model, - phase="pretrain", - ) - - # For checkpointing logic - if not args.do_target_task_training: - strict = True - else: - strict = False - - if args.do_target_task_training: - # Train on target tasks - pre_target_train_path = setup_target_task_training(args, target_tasks, model, strict) - target_tasks_to_train = copy.deepcopy(target_tasks) - # Check for previous target train checkpoints - task_to_restore, _, _ = check_for_previous_checkpoints( - args.run_dir, target_tasks_to_train, "target_train", args.load_model - ) - if task_to_restore is not None: - # If there is a task to restore from, target train only on target tasks - # including and following that task. - last_task_index = [task.name for task in target_tasks_to_train].index(task_to_restore) - target_tasks_to_train = target_tasks_to_train[last_task_index:] - for task in target_tasks_to_train: - # Skip tasks that should not be trained on. - if task.eval_only_task: - continue - - params_to_train = load_model_for_target_train_run( - args, pre_target_train_path, model, strict, task, cuda_device - ) - trainer, _, opt_params, schd_params = build_trainer( - args, - cuda_device, - [task.name], - model, - args.run_dir, - task.val_metric_decreases, - phase="target_train", - ) - - _ = trainer.train( - tasks=[task], - stop_metric=task.val_metric, - batch_size=args.batch_size, - weighting_method=args.weighting_method, - scaling_method=args.scaling_method, - train_params=params_to_train, - optimizer_params=opt_params, - scheduler_params=schd_params, - load_model=(task.name == task_to_restore), - phase="target_train", - ) - - if args.do_full_eval: - log.info("Evaluating...") - splits_to_write = evaluate.parse_write_preds_arg(args.write_preds) - - # Evaluate on target_tasks. - for task in target_tasks: - # Find the task-specific best checkpoint to evaluate on. - task_params = get_model_attribute(model, "_get_task_params", cuda_device) - task_to_use = task_params(task.name).get("use_classifier", task.name) - ckpt_path = get_best_checkpoint_path(args, "eval", task_to_use) - assert ckpt_path is not None - load_model_state(model, ckpt_path, cuda_device, skip_task_models=[], strict=strict) - evaluate_and_write(args, model, [task], splits_to_write, cuda_device) - - if args.delete_checkpoints_when_done and not args.keep_all_checkpoints: - log.info("Deleting all checkpoints.") - delete_all_checkpoints(args.run_dir) - - log.info("Done!") - - -if __name__ == "__main__": - try: - main(sys.argv[1:]) - if EMAIL_NOTIFIER is not None: - EMAIL_NOTIFIER(body="Run completed successfully!", prefix="") - except BaseException as e: - # Make sure we log the trace for any crashes before exiting. - log.exception("Fatal error in main():") - if EMAIL_NOTIFIER is not None: - import traceback - - tb_lines = traceback.format_exception(*sys.exc_info()) - EMAIL_NOTIFIER(body="".join(tb_lines), prefix="FAILED") - raise e # re-raise exception, in case debugger is attached. - sys.exit(1) - sys.exit(0) diff --git a/jiant/allennlp_mods/correlation.py b/jiant/allennlp_mods/correlation.py deleted file mode 100644 index 662062da9..000000000 --- a/jiant/allennlp_mods/correlation.py +++ /dev/null @@ -1,134 +0,0 @@ -""" Metric class for tracking correlations by saving predictions """ -import numpy as np -import torch -from allennlp.training.metrics.metric import Metric -from overrides import overrides -from scipy.stats import pearsonr, spearmanr -from sklearn.metrics import confusion_matrix, matthews_corrcoef - - -@Metric.register("fastMatthews") -class FastMatthews(Metric): - """Fast version of Matthews correlation. - - Computes confusion matrix on each batch, and computes MCC from this when - get_metric() is called. Should match the numbers from the Correlation() - class, but will be much faster and use less memory on large datasets. - """ - - def __init__(self, n_classes=2): - assert n_classes >= 2 - self.n_classes = n_classes - self.reset() - - def __call__(self, predictions, labels): - # Convert from Tensor if necessary - if isinstance(predictions, torch.Tensor): - predictions = predictions.cpu().numpy() - if isinstance(labels, torch.Tensor): - labels = labels.cpu().numpy() - - assert predictions.dtype in [np.int32, np.int64, int] - assert labels.dtype in [np.int32, np.int64, int] - - C = confusion_matrix( - labels.ravel(), predictions.ravel(), labels=np.arange(self.n_classes, dtype=np.int32) - ) - assert C.shape == (self.n_classes, self.n_classes) - self._C += C - - def mcc_from_confmat(self, C): - # Code below from - # https://github.com/scikit-learn/scikit-learn/blob/ed5e127b/sklearn/metrics/classification.py#L460 - t_sum = C.sum(axis=1, dtype=np.float64) - p_sum = C.sum(axis=0, dtype=np.float64) - n_correct = np.trace(C, dtype=np.float64) - n_samples = p_sum.sum() - cov_ytyp = n_correct * n_samples - np.dot(t_sum, p_sum) - cov_ypyp = n_samples ** 2 - np.dot(p_sum, p_sum) - cov_ytyt = n_samples ** 2 - np.dot(t_sum, t_sum) - mcc = cov_ytyp / np.sqrt(cov_ytyt * cov_ypyp) - - if np.isnan(mcc): - return 0.0 - else: - return mcc - - def get_metric(self, reset=False): - # Compute Matthews correlation from confusion matrix. - # see https://en.wikipedia.org/wiki/Matthews_correlation_coefficient - correlation = self.mcc_from_confmat(self._C) - if reset: - self.reset() - return correlation - - @overrides - def reset(self): - self._C = np.zeros((self.n_classes, self.n_classes), dtype=np.int64) - - -@Metric.register("correlation") -class Correlation(Metric): - """Aggregate predictions, then calculate specified correlation""" - - def __init__(self, corr_type): - self._predictions = [] - self._labels = [] - if corr_type == "pearson": - corr_fn = pearsonr - elif corr_type == "spearman": - corr_fn = spearmanr - elif corr_type == "matthews": - corr_fn = matthews_corrcoef - else: - raise ValueError("Correlation type not supported") - self._corr_fn = corr_fn - self.corr_type = corr_type - - def _correlation(self, labels, predictions): - corr = self._corr_fn(labels, predictions) - if self.corr_type in ["pearson", "spearman"]: - corr = corr[0] - return corr - - def __call__(self, predictions, labels): - """ Accumulate statistics for a set of predictions and labels. - - Values depend on correlation type; Could be binary or multivalued. This is handled by sklearn. - - Args: - predictions: Tensor or np.array - labels: Tensor or np.array of same shape as predictions - """ - # Convert from Tensor if necessary - if isinstance(predictions, torch.Tensor): - predictions = predictions.cpu().numpy() - if isinstance(labels, torch.Tensor): - labels = labels.cpu().numpy() - - # Verify shape match - assert predictions.shape == labels.shape, ( - "Predictions and labels must" - " have matching shape. Got:" - " preds=%s, labels=%s" % (str(predictions.shape), str(labels.shape)) - ) - if self.corr_type == "matthews": - assert predictions.dtype in [np.int32, np.int64, int] - assert labels.dtype in [np.int32, np.int64, int] - - predictions = list(predictions.flatten()) - labels = list(labels.flatten()) - - self._predictions += predictions - self._labels += labels - - def get_metric(self, reset=False): - correlation = self._correlation(self._labels, self._predictions) - if reset: - self.reset() - return correlation - - @overrides - def reset(self): - self._predictions = [] - self._labels = [] diff --git a/jiant/allennlp_mods/elmo_text_field_embedder.py b/jiant/allennlp_mods/elmo_text_field_embedder.py deleted file mode 100644 index c4ce36596..000000000 --- a/jiant/allennlp_mods/elmo_text_field_embedder.py +++ /dev/null @@ -1,155 +0,0 @@ -# Modified from allennlp/allennlp/modules/text_field_embedders/basic_text_field_embedder.py -# This textfield embedder is compatible with multi- output representation ELMo. In the Basic -# version, the single ELMo output representation can be simply concatenated. In multi-output -# representation, we need to first select the representation that is used. - -# A wrapper class for Elmo is also included here. - -from typing import Dict - -import torch -from allennlp.common import Params -from allennlp.common.checks import ConfigurationError -from allennlp.data import Vocabulary -from allennlp.modules import Elmo -from allennlp.modules.text_field_embedders.text_field_embedder import TextFieldEmbedder -from allennlp.modules.time_distributed import TimeDistributed -from allennlp.modules.token_embedders.token_embedder import TokenEmbedder -from overrides import overrides - - -@TokenEmbedder.register("elmo_token_embedder_wrapper") -class ElmoTokenEmbedderWrapper(TokenEmbedder): - """ - Wraps the Elmo call so that the parameters are saved correctly - - Forwards all calls to Elmo - """ - - def __init__( - self, - options_file: str, - weight_file: str, - do_layer_norm: bool = False, - dropout: float = 0.5, - requires_grad: bool = False, - projection_dim: int = None, - num_output_representations: int = 1, - ) -> None: - super(ElmoTokenEmbedderWrapper, self).__init__() - - # other arguments can be passed in when needed - self._elmo = Elmo( - options_file=options_file, - weight_file=weight_file, - num_output_representations=num_output_representations, - dropout=dropout, - ) - - def get_output_dim(self): - return self._elmo.get_output_dim() - - def forward( - self, inputs: torch.Tensor - ) -> Dict[str, torch.Tensor]: # pylint: disable=arguments-differ - return self._elmo(inputs) - - # this is also deferred to elmo - @classmethod - def from_params(cls, params: Params): - self._elmo = Elmo.from_params(params) - return self - - -@TextFieldEmbedder.register("elmo") -class ElmoTextFieldEmbedder(TextFieldEmbedder): - """ - forward() now accepts classifier name as an argument, which tells the embedder which ELMo representation - to return. init() also requires a dict of classifier names (i.e. the number of tasks that need their own - ELMo scalars). which map to an int corresponding to their elmo scalars in the elmo object. These are - names (strings) and not necessarily the same as task names (e.g. mnli for mnli-diagnostic). - - This is a ``TextFieldEmbedder`` that wraps a collection of :class:`TokenEmbedder` objects. Each - ``TokenEmbedder`` embeds or encodes the representation output from one - :class:`~allennlp.data.TokenIndexer`. As the data produced by a - :class:`~allennlp.data.fields.TextField` is a dictionary mapping names to these - representations, we take ``TokenEmbedders`` with corresponding names. Each ``TokenEmbedders`` - embeds its input, and the result is concatenated in an arbitrary order. - """ - - def __init__( - self, - token_embedders: Dict[str, TokenEmbedder], - classifiers: Dict[str, int], - elmo_chars_only=False, # Flag ensuring we are using real ELMo - sep_embs_for_skip=False, - ) -> None: # Flag indicating separate scalars per task - super(ElmoTextFieldEmbedder, self).__init__() - self._token_embedders = token_embedders - for key, embedder in token_embedders.items(): - name = "token_embedder_%s" % key - self.add_module(name, embedder) - self.task_map = classifiers # map handling classifier_name -> scalar idx - self.elmo_chars_only = elmo_chars_only - self.sep_embs_for_skip = sep_embs_for_skip - - @overrides - def get_output_dim(self) -> int: - output_dim = 0 - for embedder in self._token_embedders.values(): - output_dim += embedder.get_output_dim() - return output_dim - - def forward( - self, - text_field_input: Dict[str, torch.Tensor], - classifier_name: str = "@pretrain@", - num_wrapping_dims: int = 0, - ) -> torch.Tensor: - if self._token_embedders.keys() != text_field_input.keys(): - message = "Mismatched token keys: %s and %s" % ( - str(self._token_embedders.keys()), - str(text_field_input.keys()), - ) - raise ConfigurationError(message) - embedded_representations = [] - keys = sorted(text_field_input.keys()) - for key in keys: - tensor = text_field_input[key] - # Note: need to use getattr here so that the pytorch voodoo - # with submodules works with multiple GPUs. - embedder = getattr(self, "token_embedder_{}".format(key)) - for _ in range(num_wrapping_dims): - embedder = TimeDistributed(embedder) - token_vectors = embedder(tensor) - - # Changed vs original: - # If we want separate scalars/task, figure out which representation to use, since - # embedder create a representation for _all_ sets of scalars. This can be optimized - # with more wrapper classes but we compute all of them for now. - # The shared ELMo scalar weights version all use the @pretrain@ embeddings. - # There must be at least as many ELMo representations as the highest index in - # self.task_map, otherwise indexing will fail. - if key == "elmo" and not self.elmo_chars_only: - if self.sep_embs_for_skip: - token_vectors = token_vectors["elmo_representations"][ - self.task_map[classifier_name] - ] - else: - token_vectors = token_vectors["elmo_representations"][ - self.task_map["@pretrain@"] - ] - - # optional projection step that we are ignoring. - embedded_representations.append(token_vectors) - return torch.cat(embedded_representations, dim=-1) - - @classmethod - def from_params(cls, vocab: Vocabulary, params: Params) -> "BasicTextFieldEmbedder": - token_embedders = {} - keys = list(params.keys()) - for key in keys: - embedder_params = params.pop(key) - token_embedders[key] = TokenEmbedder.from_params(vocab, embedder_params) - params.assert_empty(cls.__name__) - return cls(token_embedders) diff --git a/jiant/allennlp_mods/multilabel_field.py b/jiant/allennlp_mods/multilabel_field.py deleted file mode 100644 index d3f6a2f25..000000000 --- a/jiant/allennlp_mods/multilabel_field.py +++ /dev/null @@ -1,147 +0,0 @@ -# Patched version of AllenNLP's MultiLabelField, such that empty_field() -# works properly in the case where skip_indexing=False. - -import logging -from typing import Dict, Optional, Sequence, Set, Union, cast - -import torch -from allennlp.common.checks import ConfigurationError -from allennlp.data.fields.field import Field -from allennlp.data.vocabulary import Vocabulary -from overrides import overrides - -logger = logging.getLogger(__name__) # pylint: disable=invalid-name - - -class MultiLabelField(Field[torch.Tensor]): - """ - A ``MultiLabelField`` is an extension of the :class:`LabelField` that allows for multiple labels. - It is particularly useful in multi-label classification where more than one label can be correct. - As with the :class:`LabelField`, labels are either strings of text or 0-indexed integers - (if you wish to skip indexing by passing skip_indexing=True). - If the labels need indexing, we will use a :class:`Vocabulary` to convert the string labels - into integers. - - This field will get converted into a vector of length equal to the vocabulary size with - one hot encoding for the labels (all zeros, and ones for the labels). - - Parameters - ---------- - labels : ``Sequence[Union[str, int]]`` - label_namespace : ``str``, optional (default="labels") - The namespace to use for converting label strings into integers. We map label strings to - integers for you (e.g., "entailment" and "contradiction" get converted to 0, 1, ...), - and this namespace tells the ``Vocabulary`` object which mapping from strings to integers - to use (so "entailment" as a label doesn't get the same integer id as "entailment" as a - word). If you have multiple different label fields in your data, you should make sure you - use different namespaces for each one, always using the suffix "labels" (e.g., - "passage_labels" and "question_labels"). - skip_indexing : ``bool``, optional (default=False) - If your labels are 0-indexed integers, you can pass in this flag, and we'll skip the - indexing step. If this is ``False`` and your labels are not strings, - this throws a ``ConfigurationError``. - num_labels : ``int``, optional (default=None) - If ``skip_indexing=True``, the total number of possible labels should be provided, which is - required to decide the size of the output tensor. `num_labels` should equal largest - label id + 1. If ``skip_indexing=False``, `num_labels` is not required. - - """ - - # It is possible that users want to use this field with a namespace which uses OOV/PAD tokens. - # This warning will be repeated for every instantiation of this class (i.e for every data - # instance), spewing a lot of warnings so this class variable is used to only log a single - # warning per namespace. - _already_warned_namespaces: Set[str] = set() - - def __init__( - self, - labels: Sequence[Union[str, int]], - label_namespace: str = "labels", - skip_indexing: bool = False, - num_labels: Optional[int] = None, - ) -> None: - self.labels = labels - self._label_namespace = label_namespace - self._label_ids = None - self._maybe_warn_for_namespace(label_namespace) - self._num_labels = num_labels - self._skip_indexing = skip_indexing - - if skip_indexing: - if not all(isinstance(label, int) for label in labels): - raise ConfigurationError( - "In order to skip indexing, your labels must be integers. " - "Found labels = {}".format(labels) - ) - if not num_labels: - raise ConfigurationError("In order to skip indexing, num_labels can't be None.") - - if not all(cast(int, label) < num_labels for label in labels): - raise ConfigurationError( - "All labels should be < num_labels. " - "Found num_labels = {} and labels = {} ".format(num_labels, labels) - ) - - self._label_ids = labels - else: - if not all(isinstance(label, str) for label in labels): - raise ConfigurationError( - "MultiLabelFields expects string labels if skip_indexing=False. " - "Found labels: {}".format(labels) - ) - - def _maybe_warn_for_namespace(self, label_namespace: str) -> None: - if not (label_namespace.endswith("labels") or label_namespace.endswith("tags")): - if label_namespace not in self._already_warned_namespaces: - logger.warning( - "Your label namespace was '%s'. We recommend you use a namespace " - "ending with 'labels' or 'tags', so we don't add UNK and PAD tokens by " - "default to your vocabulary. See documentation for " - "`non_padded_namespaces` parameter in Vocabulary.", - self._label_namespace, - ) - self._already_warned_namespaces.add(label_namespace) - - @overrides - def count_vocab_items(self, counter: Dict[str, Dict[str, int]]): - if self._label_ids is None: - for label in self.labels: - counter[self._label_namespace][label] += 1 # type: ignore - - @overrides - def index(self, vocab: Vocabulary): - if self._label_ids is None: - self._label_ids = [ - vocab.get_token_index(label, self._label_namespace) # type: ignore - for label in self.labels - ] - if not self._num_labels: - self._num_labels = vocab.get_vocab_size(self._label_namespace) - - @overrides - def get_padding_lengths(self) -> Dict[str, int]: # pylint: disable=no-self-use - return {} - - @overrides - def as_tensor(self, padding_lengths: Dict[str, int], cuda_device: int = -1) -> torch.Tensor: - # pylint: disable=unused-argument - - tensor = torch.zeros(self._num_labels) # vector of zeros - if self._label_ids: - tensor.scatter_(0, torch.LongTensor(self._label_ids), 1) - - return tensor if cuda_device == -1 else tensor.cuda(cuda_device) - - @overrides - def empty_field(self): - return MultiLabelField( - [], - self._label_namespace, - skip_indexing=self._skip_indexing, - num_labels=self._num_labels, - ) - - def __str__(self) -> str: - return ( - f"MultiLabelField with labels: {self.labels} in namespace: '{self._label_namespace}'.'" - ) diff --git a/jiant/allennlp_mods/numeric_field.py b/jiant/allennlp_mods/numeric_field.py deleted file mode 100644 index a1c86ac0c..000000000 --- a/jiant/allennlp_mods/numeric_field.py +++ /dev/null @@ -1,78 +0,0 @@ -import logging -from typing import Dict, Union - -import numpy -import torch -from allennlp.common.checks import ConfigurationError -from allennlp.data.fields.field import Field -from allennlp.data.vocabulary import Vocabulary -from overrides import overrides -from torch.autograd import Variable - -logger = logging.getLogger(__name__) # pylint: disable=invalid-name - - -class NumericField(Field[numpy.ndarray]): - """ - A ``LabelField`` is a categorical label of some kind, where the labels are either strings of - text or 0-indexed integers (if you wish to skip indexing by passing skip_indexing=True). - If the labels need indexing, we will use a :class:`Vocabulary` to convert the string labels - into integers. - - This field will get converted into an integer index representing the class label. - - Parameters - ---------- - label : ``Union[str, int]`` - label_namespace : ``str``, optional (default="labels") - The namespace to use for converting label strings into integers. We map label strings to - integers for you (e.g., "entailment" and "contradiction" get converted to 0, 1, ...), - and this namespace tells the ``Vocabulary`` object which mapping from strings to integers - to use (so "entailment" as a label doesn't get the same integer id as "entailment" as a - word). If you have multiple different label fields in your data, you should make sure you - use different namespaces for each one, always using the suffix "labels" (e.g., - "passage_labels" and "question_labels"). - skip_indexing : ``bool``, optional (default=False) - If your labels are 0-indexed integers, you can pass in this flag, and we'll skip the indexing - step. If this is ``False`` and your labels are not strings, this throws a ``ConfigurationError``. - """ - - def __init__(self, label: Union[float, int], label_namespace: str = "labels") -> None: - self.label = label - self._label_namespace = label_namespace - self._label_id = numpy.array(label, dtype=numpy.float32) - if not (self._label_namespace.endswith("labels") or self._label_namespace.endswith("tags")): - logger.warning( - "Your label namespace was '%s'. We recommend you use a namespace " - "ending with 'labels' or 'tags', so we don't add UNK and PAD tokens by " - "default to your vocabulary. See documentation for " - "`non_padded_namespaces` parameter in Vocabulary.", - self._label_namespace, - ) - - # idk what this is for - @overrides - def count_vocab_items(self, counter: Dict[str, Dict[str, int]]): - if self._label_id is None: - counter[self._label_namespace][self.label] += 1 # type: ignore - - @overrides - def get_padding_lengths(self) -> Dict[str, int]: # pylint: disable=no-self-use - return {} - - def as_array( - self, padding_lengths: Dict[str, int] - ) -> numpy.ndarray: # pylint: disable=unused-argument - return numpy.asarray([self._label_id]) - - @overrides - def as_tensor( - self, padding_lengths: Dict[str, int], cuda_device: int = -1, for_training: bool = True - ) -> torch.Tensor: # pylint: disable=unused-argument - label_id = self._label_id.tolist() - tensor = Variable(torch.FloatTensor([label_id]), volatile=not for_training) - return tensor if cuda_device == -1 else tensor.cuda(cuda_device) - - @overrides - def empty_field(self): - return NumericField(0, self._label_namespace) diff --git a/jiant/config/base_mlm_roberta.conf b/jiant/config/base_mlm_roberta.conf deleted file mode 100644 index 2678a5852..000000000 --- a/jiant/config/base_mlm_roberta.conf +++ /dev/null @@ -1,19 +0,0 @@ -// Base config file for mlm experiments wit roberta -include "defaults.conf" - -early_stopping_method=auto // Early stopping method. Options: task_name to only do early stopping based - // on a specific task, 'auto': use the macro_avg - -// Multi-task Training -weighting_method = proportional // Weighting method for task sampling, relative to the number of - // training examples in each task: - // Options: uniform, power_, softmax_ - // proportional, proportional_log_batch, and - // proportional_log_example (plus the less-useful inverse, - // inverse_log_example, and inverse_log_batch). - // Additionally, we include the T5 method of examples-proportional-mixing. - // See relevant source code for details. -scaling_method = uniform // Method for scaling loss: - // Options: uniform, max_power_, max_proportional, - // max_proportional_log, max_inverse, max_inverse_log - // max_epoch_ diff --git a/jiant/config/ccg_bert.conf b/jiant/config/ccg_bert.conf deleted file mode 100644 index 7f780fe7d..000000000 --- a/jiant/config/ccg_bert.conf +++ /dev/null @@ -1,26 +0,0 @@ -// Base config file for CCG experiments. -include "defaults.conf" - -pretrain_tasks = ccg -target_tasks = ccg -input_module = bert-base-uncased -do_target_task_training = 0 -transfer_paradigm = finetune - -max_seq_len = 510 -reindex_tasks = ccg -sent_enc = none -sep_embs_for_skip = 1 -skip_embs = 1 - -// BERT-specific setup -classifier = log_reg // following BERT paper - -dropout = 0.1 // following BERT paper -optimizer = bert_adam -max_epochs = 3 -lr = .00001 -min_lr = .0000001 -lr_patience = 4 -patience = 20 -max_vals = 10000 diff --git a/jiant/config/copa_bert.conf b/jiant/config/copa_bert.conf deleted file mode 100644 index 0c236a35f..000000000 --- a/jiant/config/copa_bert.conf +++ /dev/null @@ -1,36 +0,0 @@ -// An example configuration for the CommitmentBank task with BERT. -// Run with: -// python main.py --config_file jiant/config/cb_bert.conf - -// This imports the defaults, which can be overridden below. -include "defaults.conf" - -// Basics -exp_name = copa_with_bert -list_params = 0 // Quieter logs, since we're not experimenting with new or exciting architectures. -write_preds = test // Write test set predictions to disk for use on SuperGLUE if desired. - -// Standard setup for training on a single target task -pretrain_tasks = copa -target_tasks = copa -do_pretrain = 1 -do_target_task_training = 0 -do_full_eval = 1 - -// Typical BERT base setup -input_module = bert-base-uncased -transfer_paradigm = finetune -classifier = log_reg -optimizer = bert_adam -lr = 0.00001 -sent_enc = none -sep_embs_for_skip = 1 -max_seq_len = 510 -dropout = 0.1 - -// Trainer setup for small tasks with BERT -val_interval = 10 -batch_size = 12 -max_epochs = 4 - - diff --git a/jiant/config/defaults.conf b/jiant/config/defaults.conf deleted file mode 100644 index 4cbbd9d57..000000000 --- a/jiant/config/defaults.conf +++ /dev/null @@ -1,519 +0,0 @@ -// Default config file. -// Set values here, then override them in custom configs by including this at -// the top: -// -// my_experiment.conf: -// include "defaults.conf" -// -// exp_name = my_expt -// run_name = run1 -// pretrain_tasks = "mnli,qnli" -// -// ... or in a command line flag: -// -// $ python main.py --config_file jiant/config/defaults.conf \ -// --overrides "exp_name = my_expt, run_name = run1, pretrain_tasks = \"mnli,qnli\"" -// -// This file uses HOCON, which is a JSON/YAML-like format that supports -// includes, references, and object merging semantics. For reference, see: -// -// https://github.com/lightbend/config/blob/master/HOCON.md - - -// Misc. Logistics // - -cuda = auto // GPU ID. Set to -1 for CPU, "auto" for all available GPUs on machine and - // a comma-delimited list of GPU IDs for a subset of GPUs. -random_seed = 1234 // Global random seed, used in both Python and PyTorch random number generators. -track_batch_utilization = 0 // Track % of each batch that is padding tokens (for tasks with field - // 'input1'). - - -// Paths and Logging // - -// You'll generally have to override these: -project_dir = ${JIANT_PROJECT_PREFIX} // The base directory for model output. -exp_name = my-experiment // Experiment name, will be a subdirectory of project_dir. This - // directory will contain all run directories, a results summary file, - // and preprocessed data files. -run_name = tuning-0 // Run name, will be a subdirectory of exp_name. This directory will contain - // logs, checkpoints, and model predictions. -data_dir = ${JIANT_DATA_DIR} // Base directory in which to look for raw data subdirectories. This - // could be the glue_data directory created by download_glue_data.py. - -// You may want to override these: -global_ro_exp_dir = "" // If you're using very large datasets for which preprocessing - // is slow, you can set this to point to a directory for a past experiment - // (different from the current one), and the 'preproc' index files will - // be read from that directory to save time. If this directory does not - // exist, all data will be preprocessed as usual without failing. -remote_log_name = ${exp_name}"__"${run_name} // Log name for GCP remote logging, if used. This - // should be globally unique to your run. Usually - // safe to ignore. - -// You can safely ignore these, and they'll be set automatically: -exp_dir = ${project_dir}"/"${exp_name}"/" -run_dir = ${project_dir}"/"${exp_name}"/"${run_name} -local_log_path = ${run_dir}"/log.log" -list_params = 1 // Before training, print a list of all trainable model parameters with their - // shapes. Takes up a lot of log space, but useful for debugging. - - -// Tasks // - -pretrain_tasks = sst // Comma-separated list of pretraining tasks or 'glue' or 'superglue' or 'none'. - // If there are multiple entries, the list should contain no spaces, and - // should be enclosed in quotes. When using command line overrides, you need - // to escape these quotes: - // python main.py --overrides "pretrain_tasks = \"glue,ccg\"" - // Note: The code expects this to be nonempty in most cases. If you want to - // train and evaluate on a single task without doing any new pretraining, - // you should set target_tasks and pretraining_tasks to the same task, set - // do_pretrain to 1, and do_target_task_training to 0. -target_tasks = glue // Target tasks, for use in both target_task_training - // (if do_target_training = 1) and the final evaluation, - // (if do_full_eval = 1), and is in the same list format as pretrain_tasks. - - -// Execution, Saving, and Loading // - -// Three main stages of operation -do_pretrain = 1 // Run training on the tasks in pretrain_tasks. -do_target_task_training = 1 // After do_pretrain, train on the target tasks in target_tasks. -do_full_eval = 1 // Evaluate on the tasks in target_tasks. - -// Related configuration -load_model = 1 // If true, restore from checkpoint when starting do_pretrain. No impact on - // do_target_task_training. -transfer_paradigm = "frozen" // How to use pretrained model parameters during target task training. - // Applies to GPT, BERT, and pretrained sent_enc encoders. - // Options: "frozen", "finetune" - // "frozen" will train the downstream models on fixed - // representations from the encoder model. - // "finetune" will update the parameters of the encoders models as - // well as the downstream models. (This disables d_proj.) -load_target_train_checkpoint = none // If not "none", load the specified model_state checkpoint - // file when starting do_target_task_training. - // Supports * wildcards. -load_eval_checkpoint = none // If not "none", load the specified model_state checkpoint - // file when doing do_full_eval. - // Supports * wildcards. - -allow_untrained_encoder_parameters = 0 // Set for experiments involving random untrained sent_enc - // encoders only. Allows do_target_task_training and - // do_full_eval to proceed without pretraining. -allow_reuse_of_pretraining_parameters = 0 // Set to 1 to allow task models that were trained - // during pretraining to be reused in - // do_target_task_training. This may behave incorrectly - // if a run is stopped and restarted in - // do_target_task_training (issues #285, #290). -allow_missing_task_map = 0 // Dangerous: If true, ignore missing classifier_task_map.json - // Only relevant to runs that use ELMo. This is needed for bare-ELMo - // probing, since the pretraining phase is skipped for these models. -reload_tasks = 0 // If true, force the rebuilding of the task files in the experiment directory, - // even if they exist. -reload_indexing = 0 // If true, force the rebuilding of the index files in preproc/ for tasks in - // reindex_tasks, even if they exist. -reindex_tasks = "" // See reload_indexing above. -reload_vocab = 0 // If true, force the rebuilding of the vocabulary files in the experiment - // directory. For classification and - // regression tasks with the default ELMo-style character handling, there - // is no vocabulary. - -// Learning curves -target_train_data_fraction = 1 // Use only the specified fraction of the training data in the - // do_target_task_training phase. Should not impact pretraining, - // even for the same task. - // If target_train_data_fraction and pretrain_data_fraction are equal, - // then the training set for pretraining and target tasks will be the same. -pretrain_data_fraction = 1 // Use only the specified fraction of the training data in the - // do_pretrain phase. Should not impact target-phase training, even for - // the same task. - // Note: This uses rejection sampling at training time, so it can slow - // down training for small fractions (<5%). - - -// Training options // - -// Optimization -trainer_type = sampling // Type of trainer object. Currently only one option: 'sampling' -batch_size = 32 // Training batch size. -optimizer = adam // Optimizer. All valid AllenNLP options are available, including 'sgd'. - // Use 'bert_adam' for reproducing BERT experiments. - // 'adam' uses the newer AMSGrad variant. - // Warning: bert_adam is designed for cases where the number of epochs is known - // in advance, so it may not behave reasonably unless max_epochs is set to a - // reasonable positive value. -lr = 0.0001 // Initial learning rate. -min_lr = 0.000001 // Minimum learning rate. Training will stop when our explicit LR decay lowers - // the LR below this point or if any other stopping criterion applies. -max_grad_norm = 5.0 // Maximum gradient norm, for use in clipping. -lr_patience = 1 // Patience to use (in validation checks) before decaying the learning rate. - // Learning rate will decay after lr_patience + 1 validation checks have - // completed with no improvement in validation score. -lr_decay_factor = 0.5 // Factor by which to decay LR (multiplicative) when lr_patience is reached. -scheduler_threshold = 0.0001 // Threshold used in deciding when to lower learning rate. - -// Validation, Checkpointing, and Early Stopping -val_data_limit = 5000 // Maximum number of examples to be used during mid-training validations. - // We use the _first_ N (e.g., 5000) examples from each dev set. Does not - // apply to the final validation run at the end of main.py that is invoked - // by do_full_eval. -val_interval = 1000 // Number of gradient steps to take between validation checks. Note that - // the stopping criteria are only checked at these intervals. -accumulation_steps = 1 // The number of batches for which to accumulate gradients before taking - // an optimizer step. If accumulation_steps = 2, then two batches/updates - // are processed before averaging the gradients. Training metrics (e.g., - // loss) are reported at step intervals, i.e., training with batch_size - // = n and accumulation_steps = 2 simulates the training process with - // batch_size = 2n and accumulation_steps = 1, with lower peak memory - // usage and longer step time. -max_vals = 1000 // Maximum number of validation checks. Will stop once this limit has been - // reached. This cannot be disabled, but if you plan to rely on max_epochs or - // min_lr instead for stopping training, simply set it to a very high number. -max_epochs = -1 // If positive, maximum number of epochs (full pass over a task's training data) - // to train for. Training will stop once it hits max_epochs for any task or hits - // or any other stopping criterion (max validations, minimum learning). We only - // check this criterion when doing validation, so if val_interval is too high, - // especially if it's higher than one epoch's worth of steps, it's possible to - // significantly overshoot the intended number of epochs. - -early_stopping_method=auto // Early stopping method. Options: task_name to only do early stopping based - // on a specific task, 'auto': use the macro_avg -patience = 5 // Patience in early stopping. Training will stop if performance does not improve at - // all in patience + 1 validations. -keep_all_checkpoints = 0 // If set, keep checkpoint files from every validation. Otherwise, keep - // only the best and (if different) most recent. -delete_checkpoints_when_done = 0 // If set, delete *all* saved checkpoints when the run is - // complete. Be careful when using this, but it can be useful in - // cases where checkpoints are large (as with BERT), runs are - // fast, and you're confident that you won't need to run further - // tests on any specific trained model. Will not apply if - // keep_all_checkpoints is set. - -// Multi-task Training -weighting_method = proportional // Weighting method for task sampling, relative to the number of - // training examples in each task: - // Options: uniform, power_, softmax_ - // proportional, proportional_log_batch, and - // proportional_log_example (plus the less-useful inverse, - // inverse_log_example, and inverse_log_batch). - // Additionally, we include the T5 method of examples_proportional_mixing. - // To use this, set weighting_method=examples_proportional_mixingK=104857 - // See relevant source code for details. -scaling_method = uniform // Method for scaling loss: - // Options: uniform, max_power_, max_proportional, - // max_proportional_log, max_inverse, max_inverse_log - // max_epoch_ - // See relevant source code for details. -dec_val_scale = 250 // when training with increasing and decreasing val metrics - // (or multiple decreasing metrics), we use the macro average - // for early stopping, where decreasing metrics are aggregated - // as (1 - metric / dec_val_scale). - // Currently, perplexity is our only decreasing metric. - -// Evaluation -write_preds = 0 // 0 _or_ comma-separated list of splits (without spaces, options are train, val, - // or test) for which we should write predictions to disk during do_full_eval. - // Supported for GLUE tasks and a few others. You should see errors with - // unsupported tasks. -write_strict_glue_format = 0 // If true, write_preds will only write the 'index' and 'prediction' - // columns for GLUE/SuperGLUE tasks, and will use the test filenames - // expected by the GLUE evaluation server. - - -// Preprocessing // - -max_seq_len = 40 // Maximum sequence length, in tokens (usually in full tokens, even for - // models with char handling). -max_word_v_size = 30000 // Maximum input word vocab size, when creating a new embedding matrix. - // Not used for ELMo. -max_char_v_size = 250 // Maximum input char vocab size, when creating a new embedding matrix. - // Not used for ELMo. -max_targ_word_v_size = 20000 // Maximum target word vocab size for seq2seq tasks. - - -// Input Handling // - -input_module = "" // The word embedding or contextual word representation layer. - // Currently supported options: - // - scratch: Word embeddings trained from scratch. - // - glove: Loaded GloVe word embeddings. Typically used with - // tokenizer = MosesTokenizer. Note that this is not quite identical to - // the Stanford tokenizer used to train GloVe. - // - fastText: Loaded fastText word embeddings. Use with - // tokenizer = MosesTokenizer. - // - elmo: AllenNLP's ELMo contextualized word vector model hidden states. Use - // with tokenizer = MosesTokenizer. - // - elmo-chars-only: The dynamic CNN-based word embedding layer of AllenNLP's - // ELMo, but not ELMo's LSTM layer hidden states. Use with - // tokenizer = MosesTokenizer. - // - bert-base-uncased, etc.: Any BERT model from transformers. - // - roberta-base / roberta-large / roberta-large-mnli: RoBERTa model from - // transformers. - // - nyu-mll/roberta-base-1B-1 / nyu-mll/roberta-base-1B-2 / nyu-mll/roberta-base-1B-3 - // - nyu-mll/roberta-base-100M-1 / nyu-mll/roberta-base-100M-2 / nyu-mll/roberta-base-100M-3 - // - nyu-mll/roberta-base-10M-1 / nyu-mll/roberta-base-10M-2 / nyu-mll/roberta-base-10M-3 - // - nyu-mll/roberta-med-small-1M-1 / nyu-mll/roberta-med-small-1M-2 / nyu-mll/roberta-med-small-1M-3: - // MiniBERTa models pretrained by ML^2. - // - albert-base-v1 / albert-large-v1 / albert-xlarge-v1 / albert-xxlarge-v1 - // - albert-base-v2 / albert-large-v2 / albert-xlarge-v2 / albert-xxlarge-v2: - // ALBERT model from transformers. - // - xlnet-base-cased / xlnet-large-cased: XLNet Model from - // transformers. - // - openai-gpt: The OpenAI GPT language model encoder from - // transformers. - // - gpt2 / gpt2-medium / gpt2-large/ gpt2-xl: The OpenAI GPT-2 language model - // encoder from transformers. - // - transfo-xl-wt103: The Transformer-XL language model encoder from - // transformers. - // - xlm-mlm-en-2048: XLM english language model encoder from - // transformers. - // Note: Any input_module from transformers requires - // tokenizer = ${input_module} or auto. - -tokenizer = auto // The name of the tokenizer, passed to the Task constructor for - // appropriate handling during data loading. Currently supported - // options: - // - auto: Select the tokenizer that matches the model specified in - // input_module above. Usually a safe default. - // - "": Split the input data on whitespace. - // - MosesTokenizer: Our standard word tokenizer. (Support for - // other NLTK tokenizers is pending.) - // - bert-uncased-base, etc.: Use the tokenizer supplied with - // transformers that corresponds the input_module. - // - SplitChars: Splits the input into individual characters. - -word_embs_file = ${WORD_EMBS_FILE} // Path to embeddings file, used with glove and fastText. -d_word = 300 // Dimension of word embeddings, used with scratch, glove, or fastText. - -elmo_weight_file_path = none // Path to ELMo RNN weights file. Default ELMo weights will be used - // if "none". - -char_embs = 0 // Experimental. If true, train char embeddings. This is separate from the ELMo char - // component, and the two usually aren't used together. -d_char = 100 // Dimension of trained char embeddings. -n_char_filters = 100 // Number of filters in trained char CNN. -char_filter_sizes = "2,3,4,5" // Size of char CNN filters. - -transformers_output_mode = "none" // How to handle the embedding layer of the - // BERT/XLNet model: - // "none" or "top" returns only top-layer activation, - // "cat" returns top-layer concatenated with - // lexical layer, - // "only" returns only lexical layer, - // "mix" uses ELMo-style scalar mixing (with learned - // weights) across all layers. -transformers_max_layer = -1 // Maximum layer to return from BERT etc. encoder. Layer 0 is - // wordpiece embeddings. transformers_embeddings_mode - // will behave as if the is truncated at this layer, so 'top' - // will return this layer, and 'mix' will return a mix of all - // layers up to and including this layer. - // Set to -1 to use all layers. - // Used for probing experiments. - -force_include_wsj_vocabulary = 0 // Set if using PTB parsing (grammar induction) task. Makes sure - // to include WSJ vocabulary. - - -// Sentence Encoders on top of Input/Word Encoders // - -sent_enc = rnn // The type of sentence encoder we should use. This is part of the core jiant model, - // while encoders like ELMo, GPT, and BERT are input handlers, so it's safe to set - // this to 'none' when using ELMo and standard/expected to set this to 'none' when - // using GPT or BERT. - // Options: 'bow', 'rnn' (LSTM/BiLSTM), 'none' - // Specialized grammar induction options: 'prpn', 'onlstm' - // Note: 'bow' just skips the encoder step and passes the word representations to - // the task model, so it is possible to combine attention or max pooling with the - // 'bow' encoder. -bidirectional = 1 // If true, the 'rnn' encoder (if used) should be bidirectional. -d_hid = 1024 // Hidden dimension size -n_layers_enc = 2 // Number of layers for a 'rnn' sent_enc. -skip_embs = 1 // If true, concatenate the sent_enc's input (ELMo/GPT/BERT output or - // embeddings) with the sent_enc's output. -sep_embs_for_skip = 0 // Whether the skip embedding uses the same embedder object as the original - // embedding (before skip). - // Only makes a difference if we are using ELMo weights, where it allows - // the four tuned ELMo scalars to vary separately for each target task. -n_layers_highway = 0 // Number of highway layers between the embedding layer and the sent_enc layer. [Deprecated.] -dropout = 0.2 // Dropout rate. -dropout_embs = ${dropout} // Dropout rate for embeddings, same as above by default. - // NB: This only applies to trained char embs, not including ELMo. - -cove = 0 // If true, use CoVe contextualized word embeddings. Should be used with - // input_handler = glove. -cove_fine_tune = 0 // If true, CoVe params are fine-tuned. - -onlstm_chunk_size = 2 // Chunk downsizing factor for ON-LSTM master gate, dimensions - // of master gate: D/C where C is the chunk downsizing factor. -onlstm_dropconnect = 0.5 // Linear dropout between ON-LSTM layers. -onlstm_dropouti = 0.3 // Locked Dropout on input embeddings. -onlstm_dropouth = 0.3 // Locked Dropout between ON-LSTM layers. -onlstm_tying = 0 // Language Modeling tying of weights. - -n_slots = 15 // default PRPN-LM paper hyperparameter; the number of memory slots in reading network -n_lookback = 5 // default PRPN-LM paper hyperparameter; the lookback range of parsing network -resolution = 0.1 // default PRPN-LM paper hyperparameter; syntactic distance resolution -idropout = 0.5 // default PRPN-LM paper hyperparameter; dropout for layers -rdropout = 0.5 // default PRPN-LM paper hyperparameter; dropout for recurrent states -res = 0 // default PRPN-LM paper hyperparameter; number of res-net blocks in parser - - -// Task-specific Options // - -// These are _usually_ overridden for specific tasks, and are explicitly overridden in this file -// for many tasks, but defaults are set here. - -// Model -classifier = mlp // The type of the final layer(s) in classification and regression tasks. - // Options: - // log_reg: Softmax layer with no additional hidden layer. - // mlp: One tanh+layernorm+dropout layer, followed by a softmax layer. - // fancy_mlp: Same as mlp, but with an additional hidden layer. Fancy! -classifier_hid_dim = 512 // The hidden dimension size for mlp and fancy_mlp. -classifier_dropout = 0.2 // The dropout rate for mlp and fancy_mlp. -pair_attn = 1 // If true, use attn in sentence-pair classification/regression tasks. -d_hid_attn = 512 // Post-attention LSTM state size. -shared_pair_attn = 0 // If true, share pair_attn parameters across all tasks that use it. -d_proj = 512 // Size of task-specific linear projection applied before before pooling. - // Disabled when fine-tuning transformers models. -pool_type = "auto" // Type of pooling to reduce sequences of vectors into a single vector. - // Options: "auto", "max", "mean", "first", "final" - // "auto" uses "first" for plain BERT (with no sent_enc), "final" for plain - // XLNet and GPT, and "max" in all other settings. -span_classifier_loss_fn = "softmax" // Classifier loss function. Used only in some tasks (notably - // span-related tasks), not mlp/fancy_mlp. Currently supports - // sigmoid and softmax. -classifier_span_pooling = "attn" // Span pooling type (see README section on edge probing-style - // experiments for context). - // Options: 'attn' or one of the 'combination' arguments accepted - // by AllenNLP's EndpointSpanExtractor such as 'x,y'. - -edgeprobe_cnn_context = 0 // Expanded context for edge probing via CNN. - // 0 looks at only the current word, 1 adds +/- - // words (kernel width 3), etc. -edgeprobe_symmetric = 0 // If true, use same parameters for extracting span1 - // and span2 - -// Training -target_train_val_interval = 500 // Comparable to val_interval, used during - // do_target_task_training. Can be set separately per task. -target_train_max_vals = 1000 // Comparable to max_vals, used during do_target_task_training. - // Can be set separately per task. - -// Evaluation -use_classifier = "" // Used to make some task (usually a probing task with no training set) use a - // model that was trained for a different task at do_full_eval time. This - // should be overridden for each probing/auxiliary/test-only task, and set to - // the name of the task on which the associated model should be trained. - - -// Task-Specific Overrides // - -// Note: Model params apply during all phases, but trainer params like LR apply only during eval -// phase. - -glue-diagnostic { use_classifier = "mnli" } -broadcoverage-diagnostic { use_classifier = "rte-superglue" } -winogender-diagnostic { use_classifier = "rte-superglue" } - -// Optional templates. These are tuned for simple non-transformer model. -// You can inherit from them using example lines like the ones commented out below. - -glue-small-tasks-tmpl-1 { - classifier_hid_dim = 128, - d_proj = 128, - classifier_dropout = 0.4, - pair_attn = 0, - val_interval = 100, - lr = 0.0003 -} - -glue-small-tasks-tmpl-2 { - classifier_hid_dim = 256, - d_proj = 256, - classifier_dropout = 0.2, - pair_attn = 0, - val_interval = 100, - lr = 0.0003 -} - -glue-small-tasks-tmpl-3 { - classifier_hid_dim = 512, - classifier_dropout = 0.2, - pair_attn = 1, - val_interval = 1000, - lr = 0.0003 -} - -s2s { - d_hid_dec = 100 - n_layers_dec = 1 - // Options are 'Bahdanau' (a two-layer MLP to compute weights), - // 'bilinear' (weights computed as x^T W y + b) or 'none'. - attention = "Bahdanau" - output_proj_input_dim = 100 - beam_size = 10 -} - -// rte = ${glue-small-tasks-tmpl-1} -// wnli = ${glue-small-tasks-tmpl-1} -// mrpc = ${glue-small-tasks-tmpl-2} -// sst = ${glue-small-tasks-tmpl-2} -// cola = ${glue-small-tasks-tmpl-2} -// sts-b = ${glue-small-tasks-tmpl-3} -// sts-b-alt = ${glue-small-tasks-tmpl-3} -// qnli = ${glue-small-tasks-tmpl-3} -// qnli-alt = ${glue-small-tasks-tmpl-3} -// mnli = ${glue-small-tasks-tmpl-3} -// mnli-alt = ${glue-small-tasks-tmpl-3} -// qqp = ${glue-small-tasks-tmpl-3} -// qqp-alt = ${glue-small-tasks-tmpl-3} - -embeddings_train = 0 // if set to 1, embeddings will be fine tuned. - -nli-prob { - probe_path = "" -} - - -// Edge-Probing Experiments // -// See README for context. - -// Template: Not used for any single task, but extended per-task below. -edges-tmpl { - span_classifier_loss_fn = "sigmoid" // 'sigmoid' or 'softmax' - classifier_span_pooling = "attn" // 'attn' or 'x,y' - classifier_hid_dim = 256 - classifier_dropout = 0.3 - pair_attn = 0 - - // Default iters; run 50k steps. - max_vals = 100 - val_interval = 500 -} -edges-tmpl-small = ${edges-tmpl} { - // 10k steps - val_interval = 100 -} -edges-tmpl-large = ${edges-tmpl} { - // 250k steps - max_vals = 250 - val_interval = 1000 -} - -edges-pos-ontonotes = ${edges-tmpl-large} -edges-nonterminal-ontonotes = ${edges-tmpl-large} -edges-ner-ontonotes = ${edges-tmpl-large} -edges-srl-ontonotes = ${edges-tmpl-large} -edges-coref-ontonotes = ${edges-tmpl-large} - -edges-dep-ud-ewt = ${edges-tmpl-large} - -edges-spr1 = ${edges-tmpl-small} -edges-spr2 = ${edges-tmpl-small} -edges-dpr = ${edges-tmpl-small} - -edges-rel-semeval = ${edges-tmpl-small} -edges-rel-tacred = ${edges-tmpl} diff --git a/jiant/config/demo.conf b/jiant/config/demo.conf deleted file mode 100644 index 3b2086a42..000000000 --- a/jiant/config/demo.conf +++ /dev/null @@ -1,48 +0,0 @@ -// Fast demo config, used mainly for validating that an installation worked and that code -// changes don't crash. -// Run with: -// python main.py --config_file jiant/config/demo.conf - -// This is not meant to yield good performance, but for reference, here are the results -// shown at the end of a typical run with jiant 1.0: - -// micro_avg: 0.285, macro_avg: 0.285, sts-b_corr: 0.285, sts-b_pearsonr: 0.297, sts-b_spearmanr: 0.273 -// micro_avg: 0.486, macro_avg: 0.486, commitbank_accuracy: 0.696, commitbank_f1: 0.486, commitbank_precision: 0.465, commitbank_recall: 0.508 - -// Optimization is stochastic, so these numbers will vary slightly across runs. - -// This imports the defaults, which can be overridden below. -include "defaults.conf" // relative path to this file - -// write to local storage by default for this demo -exp_name = jiant-demo -run_name = mtl-sst-mrpc - -random_seed = 42 - -load_model = 0 -reload_tasks = 0 -reload_indexing = 0 -reload_vocab = 0 - -pretrain_tasks = "sst,mrpc" -target_tasks = "sts-b,commitbank" -classifier = mlp -classifier_hid_dim = 32 -max_seq_len = 10 -max_word_v_size = 1000 -pair_attn = 0 - -input_module = scratch -d_word = 50 - -sent_enc = bow -skip_embs = 0 - -batch_size = 8 - -lr = 0.0003 -val_interval = 50 -max_vals = 10 -target_train_val_interval = 10 -target_train_max_vals = 10 diff --git a/jiant/config/edgeprobe/edgeprobe_bare.conf b/jiant/config/edgeprobe/edgeprobe_bare.conf deleted file mode 100644 index f2ddcb396..000000000 --- a/jiant/config/edgeprobe/edgeprobe_bare.conf +++ /dev/null @@ -1,31 +0,0 @@ -// Run edge probing models over bare ELMo / word representations, -// without training an encoder on pre-training tasks. -// -// Use this for baseline probing & hyperparameter tuning for probing models. - -// This imports the defaults, which can be overridden below. -include "../defaults.conf" // relative path to this file - -exp_name = "" // configure this -run_name = "run" // configure this - -pretrain_tasks = "" // empty: don't run main training phase -target_tasks = "" // train classifier only - -// Eval will use task-specific params. -do_pretrain = 0 // skip main train phase -allow_untrained_encoder_parameters = 1 // allow skipping training phase -allow_missing_task_map = 1 // ignore missing classifier_task_map.json -do_target_task_training = 1 // train using eval task params -do_full_eval = 1 -write_preds = "val,test" - -lr_patience = 5 // vals until LR decay -patience = 20 // vals until early-stopping - -tokenizer = "" // use native tokenization with ELMo - -// Use no-op encoder (no params). -sent_enc = "none" -skip_embs = 1 -sep_embs_for_skip = 1 // learn task-specific ELMo scalars diff --git a/jiant/config/edgeprobe/edgeprobe_bert.conf b/jiant/config/edgeprobe/edgeprobe_bert.conf deleted file mode 100644 index 8b177adc2..000000000 --- a/jiant/config/edgeprobe/edgeprobe_bert.conf +++ /dev/null @@ -1,42 +0,0 @@ -// Run edge probing models over BERT, -// without training an encoder on pre-training tasks. -// -// Use this for baseline probing & hyperparameter tuning for probing models. -// -// You should override input_module with one of the valid BERT models, as -// defined in https://github.com/huggingface/pytorch-pretrained-BERT -// For example: -// bert-base-uncased -// bert-large-uncased -// bert-base-cased (recommended for NER) -// bert-large-cased (recommended for NER) - -// This imports the defaults, which can be overridden below. -include "../defaults.conf" // relative path to this file - -exp_name = "" // configure this -run_name = "run" // default - -pretrain_tasks = "" // empty: don't run main training phase -target_tasks = "" // train classifier only - -// Eval will use task-specific params. -do_pretrain = 0 // skip main train phase -allow_untrained_encoder_parameters = 1 // allow skipping training phase -allow_missing_task_map = 1 // ignore missing classifier_task_map.json -do_target_task_training = 1 // train using eval task params -do_full_eval = 1 -write_preds = "val,test" - -lr_patience = 5 // vals until LR decay -patience = 20 // vals until early-stopping - -input_module = "" -tokenizer = ${input_module} -max_seq_len = 512 -cove = 0 - -// Use no-op encoder (no params). -sent_enc = "none" -skip_embs = 1 // forward embeddings from lower level. -sep_embs_for_skip = 1 // use task embeddings since we skip the generic ones. diff --git a/jiant/config/edgeprobe/edgeprobe_cove.conf b/jiant/config/edgeprobe/edgeprobe_cove.conf deleted file mode 100644 index a36a5ec28..000000000 --- a/jiant/config/edgeprobe/edgeprobe_cove.conf +++ /dev/null @@ -1,33 +0,0 @@ -// Run edge probing models over CoVe, -// without training an encoder on pre-training tasks. -// -// Use this for baseline probing & hyperparameter tuning for probing models. - -// This imports the defaults, which can be overridden below. -include "../defaults.conf" // relative path to this file - -exp_name = "" // configure this -run_name = "run" // configure this - -pretrain_tasks = "" // empty: don't run main training phase -target_tasks = "" // train classifier only - -// Eval will use task-specific params. -do_pretrain = 0 // skip main train phase -allow_untrained_encoder_parameters = 1 // allow skipping training phase -allow_missing_task_map = 1 // ignore missing classifier_task_map.json -do_target_task_training = 1 // train using eval task params -do_full_eval = 1 -write_preds = "val,test" - -lr_patience = 5 // vals until LR decay -patience = 20 // vals until early-stopping - -tokenizer = "MosesTokenizer" -cove = 1 -input_module = "glove" - -// Use no-op encoder (no params). -sent_enc = "none" -skip_embs = 1 // forward embeddings from lower level. -sep_embs_for_skip = 1 // use task embeddings since we skip the generic ones. diff --git a/jiant/config/edgeprobe/edgeprobe_demo.conf b/jiant/config/edgeprobe/edgeprobe_demo.conf deleted file mode 100644 index 7c191bb4e..000000000 --- a/jiant/config/edgeprobe/edgeprobe_demo.conf +++ /dev/null @@ -1,61 +0,0 @@ -// This imports the defaults, which can be overridden below. -include "../defaults.conf" // relative path to this file - -// write to local storage by default for this demo -exp_name = "edgeprobe-demo" -run_name = "run" - -reload_tasks = 1 - -pretrain_tasks = "sst" -target_tasks = "edges-spr2" // SPR2 is small and runs quickly -do_pretrain = 1 -do_full_eval = 1 -do_target_task_training = 1 -write_preds = "val" // don't do #datascience on the test set - -classifier = "mlp" -classifier_hid_dim = 32 -max_seq_len = 10 -max_word_v_size = 5000 - -input_module = "elmo" -tokenizer = "" // use native tokenization with ELMo - -sent_enc = "rnn" -bidirectional = 1 -d_hid = 128 -pair_attn = 1 -shared_pair_attn = 0 // if true, share pair attn for pairwise tasks -n_layers_enc = 1 -skip_embs = 1 -n_layers_highway = 0 - -batch_size = 8 - - -val_interval = 100 -max_vals = 10 -eval_val_interval = 10 -eval_max_vals = 10 -weighting_method = "uniform" -scaling_method = "uniform" - -edges-tmpl += { - max_vals = 2 # vals are slow, so only run two iters for demo -} - -edges-constituent-ptb += { - # This task is slow due to # of spans, so use a short interval for demo. - val_interval = 50 -} - -edges-ccg-tag += { - # This task is slow due to # of spans, so use a short interval for demo. - val_interval = 50 -} - -edges-ccg-parse += { - # This task is slow due to # of spans, so use a short interval for demo. - val_interval = 50 -} diff --git a/jiant/config/edgeprobe/edgeprobe_existing.conf b/jiant/config/edgeprobe/edgeprobe_existing.conf deleted file mode 100644 index ba486cf1a..000000000 --- a/jiant/config/edgeprobe/edgeprobe_existing.conf +++ /dev/null @@ -1,39 +0,0 @@ -// Override config to eval an existing model. Intended to be included *after* -// that model's params.conf. Usage: -// PARAM_FILE="/path/to/trained/model/params.conf" -// python main.py -c jiant/config/defaults.conf ${PARAM_FILE} \ -// jiant/config/edgeprobe/edgeprobe_existing.conf -// -// See major_experiment_scripts/edgeprobe_example_run.sh -// for usage example. - -// Override paths from params.conf, since these might point to paths on a -// different system. -project_dir = ${JIANT_PROJECT_PREFIX} -data_dir = ${JIANT_DATA_DIR} // required - should point to data on NFS. - -// parameters you will need to set via overrides -exp_name = "" -run_name = "" -target_tasks = "" // e.g. recast-puns, or edges-srl-conll2005 -load_eval_checkpoint = "" // e.g. /path/to/model_state_eval_best.th - -exp_dir = ${project_dir}"/"${exp_name}"/" // required -run_dir = ${project_dir}"/"${exp_name}"/"${run_name} // required -local_log_path = ${run_dir}"/log.log" // log file, goes in run directory -// log name for remote logging; make as unique as possible -remote_log_name = ${exp_name}"__"${run_name} - -// Load model, but don't train. -load_model = 1 -reload_tasks = 0 -reload_indexing = 0 -reload_vocab = 0 -pretrain_tasks = "none" - -do_pretrain = 0 -do_full_eval = 1 -do_target_task_training = 1 -write_preds = "val" - -elmo_chars_only = 1 diff --git a/jiant/config/edgeprobe/edgeprobe_glove.conf b/jiant/config/edgeprobe/edgeprobe_glove.conf deleted file mode 100644 index 6b027fcb6..000000000 --- a/jiant/config/edgeprobe/edgeprobe_glove.conf +++ /dev/null @@ -1,34 +0,0 @@ -// Run edge probing models over GloVe representations, since this is the -// context-independent lexical layer used by CoVe. -// without training an encoder on pre-training tasks. -// -// Use this for baseline probing & hyperparameter tuning for probing models. - -// This imports the defaults, which can be overridden below. -include "../defaults.conf" // relative path to this file - -exp_name = "" // configure this -run_name = "run" // configure this - -pretrain_tasks = "" // empty: don't run main training phase -target_tasks = "" // train classifier only - -// Eval will use task-specific params. -do_pretrain = 0 // skip main train phase -allow_untrained_encoder_parameters = 1 // allow skipping training phase -allow_missing_task_map = 1 // ignore missing classifier_task_map.json -do_target_task_training = 1 // train using eval task params -do_full_eval = 1 -write_preds = "val,test" - -lr_patience = 5 // vals until LR decay -patience = 20 // vals until early-stopping - -tokenizer = "MosesTokenizer" // for consistency with CoVe -cove = 0 -input_module = "glove" - -// Use no-op encoder (no params). -sent_enc = "none" -skip_embs = 1 // forward embeddings from lower level. -sep_embs_for_skip = 1 // use task embeddings since we skip the generic ones. diff --git a/jiant/config/edgeprobe/edgeprobe_miniberta.conf b/jiant/config/edgeprobe/edgeprobe_miniberta.conf deleted file mode 100644 index 039f94d9e..000000000 --- a/jiant/config/edgeprobe/edgeprobe_miniberta.conf +++ /dev/null @@ -1,42 +0,0 @@ -// Run edge probing models over MiniBERTas, -// without training an encoder on pre-training tasks. -// -// Use this for baseline probing & hyperparameter tuning for probing models. -// -// You should override input_module with one of the valid MiniBERTa models, as -// defined in https://huggingface.co/nyu-mll -// For example: -// nyu-mll/roberta-base-100M-1 -// nyu-mll/roberta-med-small-1M-2 - -// This config inherits from edgeprobe_bert.conf. A clean template is created for -// each task so that training hyperparameters can be overridden. -include "./edgeprobe_bert.conf" - -edges-pos-ontonotes = null -edges-nonterminal-ontonotes = null -edges-ner-ontonotes = null -edges-srl-ontonotes = null -edges-coref-ontonotes = null -edges-dep-ud-ewt = null -edges-spr1 = null -edges-spr2 = null -edges-dpr = null -edges-rel-semeval = null -edges-tmpl-clean { - span_classifier_loss_fn = "sigmoid" // 'sigmoid' or 'softmax' - classifier_span_pooling = "attn" // 'attn' or 'x,y' - classifier_hid_dim = 256 - classifier_dropout = 0.3 - pair_attn = 0 -} -edges-pos-ontonotes = ${edges-tmpl-clean} -edges-nonterminal-ontonotes = ${edges-tmpl-clean} -edges-ner-ontonotes = ${edges-tmpl-clean} -edges-srl-ontonotes = ${edges-tmpl-clean} -edges-coref-ontonotes = ${edges-tmpl-clean} -edges-dep-ud-ewt = ${edges-tmpl-clean} -edges-spr1 = ${edges-tmpl-clean} -edges-spr2 = ${edges-tmpl-clean} -edges-dpr = ${edges-tmpl-clean} -edges-rel-semeval = ${edges-tmpl-clean} diff --git a/jiant/config/edgeprobe/edgeprobe_openai.conf b/jiant/config/edgeprobe/edgeprobe_openai.conf deleted file mode 100644 index 5cc90dacc..000000000 --- a/jiant/config/edgeprobe/edgeprobe_openai.conf +++ /dev/null @@ -1,32 +0,0 @@ -// Run edge probing models over the OpenAI Transformer LM. -// without training an encoder on pre-training tasks. -// -// Use this for baseline probing & hyperparameter tuning for probing models. - -// This imports the defaults, which can be overridden below. -include "../defaults.conf" // relative path to this file - -exp_name = "" // configure this -run_name = "run" // default - -pretrain_tasks = "" // empty: don't run main training phase -target_tasks = "" // train classifier only - -// Eval will use task-specific params. -do_pretrain = 0 // skip main train phase -allow_untrained_encoder_parameters = 1 // allow skipping training phase -allow_missing_task_map = 1 // ignore missing classifier_task_map.json -do_target_task_training = 1 // train using eval task params -do_full_eval = 1 -write_preds = "val,test" - -lr_patience = 5 // vals until LR decay -patience = 20 // vals until early-stopping - -cove = 0 -input_module = "openai-gpt" - -// Use no-op encoder (no params). -sent_enc = "none" -skip_embs = 1 // forward embeddings from lower level. -sep_embs_for_skip = 1 // use task embeddings since we skip the generic ones. diff --git a/jiant/config/edgeprobe/edgeprobe_train.conf b/jiant/config/edgeprobe/edgeprobe_train.conf deleted file mode 100644 index 601db53d5..000000000 --- a/jiant/config/edgeprobe/edgeprobe_train.conf +++ /dev/null @@ -1,35 +0,0 @@ -// Run edge probing models over bare ELMo / word representations, -// without training an encoder on pre-training tasks. -// -// Use this for baseline probing & hyperparameter tuning for probing models. - -// This imports the defaults, which can be overridden below. -include "../defaults.conf" // relative path to this file - -exp_name = "" // configure this -run_name = "run" // configure this - -pretrain_tasks = "" // set this to the train task -target_tasks = ${pretrain_tasks} // eval on same set - -// Eval will use task-specific params. -do_pretrain = 1 // use main training phase -do_target_task_training = 0 // don't separately fine-tune -do_full_eval = 1 -write_preds = "val,test" - -val_interval = 500 -max_vals = 200 -lr_patience = 5 // vals until LR decay -patience = 20 // vals until early-stopping - -elmo = 1 -elmo_chars_only = 1 // set to 0 to use full ELMo - -// Encoder params. -sent_enc = "rnn" -d_hid = 256 -n_layers_enc = 2 - -skip_embs = 1 -sep_embs_for_skip = 0 // use pretrain scalars only diff --git a/jiant/config/examples/copa_bert.conf b/jiant/config/examples/copa_bert.conf deleted file mode 100644 index 9264254a6..000000000 --- a/jiant/config/examples/copa_bert.conf +++ /dev/null @@ -1,36 +0,0 @@ -// An example configuration for the COPA task with BERT. -// Run with: -// python main.py --config_file jiant/config/examples/copa_bert.conf - -// This imports the defaults, which can be overridden below. -include "defaults.conf" - -// Basics -exp_name = copa_with_bert -list_params = 0 // Quieter logs, since we're not experimenting with new or exciting architectures. -write_preds = test // Write test set predictions to disk for use on SuperGLUE if desired. - -// Standard setup for training on a single target task -pretrain_tasks = copa -target_tasks = copa -do_pretrain = 1 -do_target_task_training = 0 -do_full_eval = 1 - -// Typical BERT base setup -input_module = bert-base-uncased -transfer_paradigm = finetune -classifier = log_reg -optimizer = bert_adam -lr = 0.00001 -sent_enc = none -sep_embs_for_skip = 1 -max_seq_len = 512 -dropout = 0.1 - -// Trainer setup for small tasks with BERT -val_interval = 10 -batch_size = 12 -max_epochs = 4 - - diff --git a/jiant/config/examples/stilts_example.conf b/jiant/config/examples/stilts_example.conf deleted file mode 100644 index e358f4f9b..000000000 --- a/jiant/config/examples/stilts_example.conf +++ /dev/null @@ -1,37 +0,0 @@ -// This config is for STILTS training [https://arxiv.org/pdf/1811.01088.pdf] -// for BERT -> MNLI -> RTE -// For this example we use BERT-base. -// Run with: -// python main.py --config_file jiant/config/examples/stilts_example.conf - -include "../defaults.conf" -pretrain_tasks = "mnli" -target_tasks = "rte" - -//Experiment configs -do_pretrain = 1 -do_target_task_training = 1 -do_full_eval = 1 - -batch_size = 24 - -write_preds = "val,test" - -//BERT-specific parameters -transformers_output_mode = "top" -sep_embs_for_skip = 1 -sent_enc = "none" -classifier = log_reg // following BERT paper - -dropout = 0.1 // following BERT paper -optimizer = bert_adam -max_epochs = 3 -lr = .00001 -min_lr = .0000001 -lr_patience = 4 -patience = 20 -max_vals = 10000 -transfer_paradigm = "finetune" - -input_module = "bert-base-uncased" - diff --git a/jiant/config/onlstm.conf b/jiant/config/onlstm.conf deleted file mode 100644 index aa78fff5b..000000000 --- a/jiant/config/onlstm.conf +++ /dev/null @@ -1,22 +0,0 @@ -// Template for grammar induction experiments with the ONLSTM sentence encoder. - -include "defaults.conf" - -bidirectional = 0 -pretrain_tasks = "wsj" -do_pretrain = 1 -do_target_task_training = 0 -do_full_eval = 1 -input_module = "scratch" -sent_enc = "onlstm" -d_hid = 1150 // default ON-LSTM paper hyperparameter -n_layers_enc = 3 // default ON-LSTM paper hyperparameter -dropout = 0.3 // default ON-LSTM paper hyperparameter -d_word = 400 // default ON-LSTM paper hyperparameter -max_seq_len = 70 -skip_embs = 0 -batch_size = 20 -optimizer = sgd -max_grad_norm = 0.5 // default in ON-LSTM paper was 0.25, changed for generalization to other datasets and tasks. -lr = 1.0 // The default in the ON-LSTM paper was 30.0, value fine tuned for jiant training code. -onlstm_chunk_size = 10 // Original value in paper was 10. Must be divisible by 4 * d_hid. \ No newline at end of file diff --git a/jiant/config/prpn.conf b/jiant/config/prpn.conf deleted file mode 100644 index cc7a75230..000000000 --- a/jiant/config/prpn.conf +++ /dev/null @@ -1,29 +0,0 @@ -include "defaults.conf" - -bidirectional = 0 -pretrain_tasks = "wsj" -target_tasks = "wsj" -do_pretrain = 1 -do_target_task_training = 0 -do_full_eval = 1 -input_module = "scratch" -sent_enc = "prpn" -d_hid = 1200 // default PRPN-LM paper hyperparameter -n_layers_enc = 2 // default PRPN-LM paper hyperparameter -dropout = 0.7 // default PRPN-LM paper hyperparameter -idropout = 0.5 // default PRPN-LM paper hyperparameter; dropout for layers -rdropout = 0.5 // default PRPN-LM paper hyperparameter; dropout for recurrent states -d_word = 800 // default PRPN-LM paper hyperparameter -n_slots=15 // default PRPN-LM paper hyperparameter; the number of memory slots in reading network -n_lookback=5 // default PRPN-LM paper hyperparameter; the lookback range of parsing network -resolution=0.1 // default PRPN-LM paper hyperparameter; syntactic distance resolution -res=0 // default PRPN-LM paper hyperparameter; number of res-net blocks in parser -max_seq_len = 70 -skip_embs = 0 -batch_size = 24 -optimizer = adam -max_grad_norm = 1 -lr_patience = 5 -lr = 0.003 -max_grad_norm = 1.0 // default in PRPN paper was 1 - diff --git a/jiant/config/seg_wix.conf b/jiant/config/seg_wix.conf deleted file mode 100644 index b28f59c8b..000000000 --- a/jiant/config/seg_wix.conf +++ /dev/null @@ -1,49 +0,0 @@ -// Template for morphological segmentation cast as a seq2seq problem. - -// This imports the defaults, which can be overridden below. -include "defaults.conf" // relative path to this file - -cuda = 0 -random_seed = 42 - -load_model = 0 -reload_tasks = 0 -reload_indexing = 0 -reload_vocab = 0 -do_pretrain = 1 -do_target_task_training = 0 -do_full_eval = 1 - -pretrain_tasks = "seg-wix" -target_tasks = "" -max_seq_len = 100 -max_word_v_size = 200 -pair_attn = 0 - -d_word = 300 -d_hid = 100 -n_layers_enc = 1 -d_proj = 100 -d_hid_attn = 100 -skip_embs = 0 -batch_size = 20 - -optimizer = adam -lr = 0.001 -tokenizer = "SplitChars" -input_module = "scratch" -val_interval = 330 -lr_patience = 10 -patience = 20 -max_vals = 35 -dropout = 0.4 - -allow_untrained_encoder_parameters = 1 - -s2s { - d_hid_dec = 100 - n_layers_dec = 1 - attention = "Bahdanau" - output_proj_input_dim = 100 - beam_size = 5 -} diff --git a/jiant/config/superglue_bert.conf b/jiant/config/superglue_bert.conf deleted file mode 100644 index 0e8a6d553..000000000 --- a/jiant/config/superglue_bert.conf +++ /dev/null @@ -1,39 +0,0 @@ -// Config settings used for SuperGLUE BERT baseline experiments. - -// This imports the defaults, which can be overridden below. -include "defaults.conf" -exp_name = "bert-large-cased" - -// Data and preprocessing settings -max_seq_len = 256 // Mainly needed for MultiRC, to avoid over-truncating - // But not 512 as that is really hard to fit in memory. - -// Model settings -input_module = "bert-large-cased" -transformers_output_mode = "top" -pair_attn = 0 // shouldn't be needed but JIC -s2s = { - attention = none -} -sent_enc = "none" -sep_embs_for_skip = 1 -classifier = log_reg // following BERT paper -transfer_paradigm = finetune // finetune entire BERT model - -// Training settings -dropout = 0.1 // following BERT paper -optimizer = bert_adam -batch_size = 4 -max_epochs = 10 -lr = .00001 -min_lr = .0000001 -lr_patience = 4 -patience = 20 -max_vals = 10000 - -// Control-flow stuff -do_pretrain = 1 -do_target_task_training = 1 -do_full_eval = 1 -write_preds = "val,test" -write_strict_glue_format = 1 diff --git a/jiant/config/superglue_bow.conf b/jiant/config/superglue_bow.conf deleted file mode 100644 index 956c05143..000000000 --- a/jiant/config/superglue_bow.conf +++ /dev/null @@ -1,55 +0,0 @@ -// Config settings used for SuperGLUE CBoW baseline experiments. - -// This imports the defaults, which can be overridden below. -include "defaults.conf" -exp_name = "superglue-bow" - -// Data and preprocessing settings -max_seq_len = 256 -tokenizer = MosesTokenizer - -// Model settings -sent_enc = "bow" -input_module = glove -skip_embs = 0 -sep_embs_for_skip = 0 -classifier = log_reg // following BERT paper -pair_attn = 0 // shouldn't be needed but JIC -s2s = { - attention = none -} -transfer_paradigm = finetune - -// Training settings -dropout = 0.1 -optimizer = adam -batch_size = 16 -max_epochs = 10 -lr = .00001 -min_lr = .0000001 -lr_patience = 4 -patience = 20 -max_vals = 10000 - -// Control flow -do_pretrain = 1 -do_target_task_training = 1 -do_full_eval = 1 -write_preds = "val,test" -write_strict_glue_format = 1 - -// Task-specific settings - -rte = ${glue-small-tasks-tmpl-1} -wnli = ${glue-small-tasks-tmpl-1} -mrpc = ${glue-small-tasks-tmpl-2} -sst = ${glue-small-tasks-tmpl-2} -cola = ${glue-small-tasks-tmpl-2} -sts-b = ${glue-small-tasks-tmpl-3} -sts-b-alt = ${glue-small-tasks-tmpl-3} -qnli = ${glue-small-tasks-tmpl-3} -qnli-alt = ${glue-small-tasks-tmpl-3} -mnli = ${glue-small-tasks-tmpl-3} -mnli-alt = ${glue-small-tasks-tmpl-3} -qqp = ${glue-small-tasks-tmpl-3} -qqp-alt = ${glue-small-tasks-tmpl-3} \ No newline at end of file diff --git a/jiant/evaluate.py b/jiant/evaluate.py deleted file mode 100644 index 03b927231..000000000 --- a/jiant/evaluate.py +++ /dev/null @@ -1,669 +0,0 @@ -""" Helper functions to evaluate a model on a dataset """ -import json -import logging as log -import os -import time -from collections import defaultdict -from csv import QUOTE_MINIMAL, QUOTE_NONE -from typing import Dict, Iterable, List, Sequence, Tuple - -import pandas as pd -import torch -from allennlp.nn.util import move_to_device -from allennlp.data.iterators import BasicIterator -from jiant import tasks as tasks_module -from jiant.tasks.tasks import ( - BooleanQuestionTask, - CommitmentTask, - COPATask, - RTESuperGLUETask, - WiCTask, - WinogradCoreferenceTask, - GLUEDiagnosticTask, -) -from jiant.tasks.qa import MultiRCTask, ReCoRDTask, QASRLTask -from jiant.tasks.edge_probing import EdgeProbingTask -from jiant.utils.utils import get_output_attribute - - -LOG_INTERVAL = 30 - - -def _format_preds(preds): - if isinstance(preds, (list, torch.Tensor)): - preds = _coerce_list(preds) - assert isinstance(preds, list), "Convert predictions to list!" - cols = {"preds": preds} - elif isinstance(preds, dict): - cols = {} - for k, v in preds.items(): - cols[f"preds_{k}"] = _coerce_list(v) - else: - raise TypeError(type(preds)) - return cols - - -def _coerce_list(preds) -> List: - if isinstance(preds, torch.Tensor): - return preds.data.tolist() - else: - return list(preds) - - -def parse_write_preds_arg(write_preds_arg: str) -> List[str]: - if write_preds_arg == 0: - return [] - elif write_preds_arg == 1: - return ["test"] - else: - return write_preds_arg.split(",") - - -def evaluate( - model, tasks: Sequence[tasks_module.Task], batch_size: int, cuda_device, split="val" -) -> Tuple[Dict, pd.DataFrame]: - """Evaluate on a dataset - {par,qst,ans}_idx are used for MultiRC and other question answering dataset""" - FIELDS_TO_EXPORT = [ - "idx", - "sent1_str", - "sent2_str", - "labels", - "pair_id", - "psg_idx", - "qst_idx", - "ans_idx", - "ans_str", - ] - # Enforce that these tasks have the 'idx' field set. - IDX_REQUIRED_TASK_NAMES = ( - tasks_module.ALL_GLUE_TASKS - + tasks_module.ALL_SUPERGLUE_TASKS - + tasks_module.ALL_COLA_NPI_TASKS - ) - model.eval() - iterator = BasicIterator(batch_size) - - all_metrics = {"micro_avg": 0.0, "macro_avg": 0.0} - all_preds = {} - n_examples_overall = 0 # n examples over all tasks - assert len(tasks) > 0, "Configured to evaluate, but specified no task to evaluate." - - for task in tasks: - log.info("Evaluating on: %s, split: %s", task.name, split) - last_log = time.time() - n_task_examples = 0 - task_preds = [] # accumulate DataFrames - assert split in ["train", "val", "test"] - generator = iterator(task.get_instance_iterable(split), num_epochs=1, shuffle=False) - for batch_idx, batch in enumerate(generator): - with torch.no_grad(): - if isinstance(cuda_device, int): - batch = move_to_device(batch, cuda_device) - out = model.forward(task=task, batch=batch, predict=True) - if task is not None: - task.update_metrics(out, batch) - - n_exs = get_output_attribute(out, "n_exs", cuda_device) - # in multi-GPU mode n_exs is expected to be a tensor, w/ single-GPU an int is expected: - if isinstance(n_exs, torch.Tensor): - n_task_examples += n_exs.item() - elif isinstance(n_exs, int): - n_task_examples += n_exs - else: - raise ValueError("n_exs is type " + type(n_exs) + ", int or Tensor is expected.") - - # get predictions - if "preds" not in out: - continue - out["preds"] = task.handle_preds(out["preds"], batch) - cols = _format_preds(out["preds"]) - if task.name in IDX_REQUIRED_TASK_NAMES: - assert "idx" in batch, f"'idx' field missing from batches " "for task {task.name}!" - for field in FIELDS_TO_EXPORT: - if field in batch: - cols[field] = _coerce_list(batch[field]) - - # Transpose data using Pandas - df = pd.DataFrame(cols) - task_preds.append(df) - - if time.time() - last_log > LOG_INTERVAL: - log.info("\tTask %s: batch %d", task.name, batch_idx) - last_log = time.time() - # task_preds will be a DataFrame with columns - # ['preds'] + FIELDS_TO_EXPORT - # for GLUE tasks, preds entries should be single scalars. - # Update metrics - task_metrics = task.get_metrics(reset=True) - for name, value in task_metrics.items(): - all_metrics["%s_%s" % (task.name, name)] = value - - # We don't want diagnostic tasks to affect the micro and macro average. - # Accuracy on diagnostic tasks is hardcoded to 0 except for winogender-diagnostic. - if task.contributes_to_aggregate_score: - all_metrics["micro_avg"] += all_metrics[task.val_metric] * n_task_examples - all_metrics["macro_avg"] += all_metrics[task.val_metric] - n_examples_overall += n_task_examples - - if not task_preds: - log.warning("Task %s: has no predictions!", task.name) - continue - - # Combine task_preds from each batch to a single DataFrame. - task_preds = pd.concat(task_preds, ignore_index=True) - - # Store predictions, sorting by index if given. - if "idx" in task_preds.columns: - log.info("Task '%s': sorting predictions by 'idx'", task.name) - task_preds.sort_values(by=["idx"], inplace=True) - all_preds[task.name] = task_preds - log.info("Finished evaluating on: %s", task.name) - - # hack for diagnostics - all_metrics["micro_avg"] /= max(n_examples_overall, 1) - all_metrics["macro_avg"] /= len(tasks) - - return all_metrics, all_preds - - -def write_preds( - tasks: Iterable[tasks_module.Task], all_preds, pred_dir, split_name, strict_glue_format=False -) -> None: - for task in tasks: - if task.name not in all_preds: - log.warning("Task '%s': missing predictions for split '%s'", task.name, split_name) - continue - - preds_df = all_preds[task.name] - # Tasks that use _write_glue_preds: - glue_style_tasks = ( - tasks_module.ALL_NLI_PROBING_TASKS - + tasks_module.ALL_GLUE_TASKS - + ["wmt"] - + tasks_module.ALL_COLA_NPI_TASKS - ) - - if task.name in glue_style_tasks: - # Strict mode: strict GLUE format (no extra cols) - strict = strict_glue_format and task.name in tasks_module.ALL_GLUE_TASKS - _write_glue_preds(task.name, preds_df, pred_dir, split_name, strict_glue_format=strict) - elif isinstance(task, EdgeProbingTask): - # Edge probing tasks, have structured output. - _write_edge_preds(task, preds_df, pred_dir, split_name) - elif isinstance(task, BooleanQuestionTask): - _write_boolq_preds( - task, preds_df, pred_dir, split_name, strict_glue_format=strict_glue_format - ) - elif isinstance(task, CommitmentTask): - _write_commitment_preds( - task, preds_df, pred_dir, split_name, strict_glue_format=strict_glue_format - ) - elif isinstance(task, COPATask): - _write_copa_preds( - task, preds_df, pred_dir, split_name, strict_glue_format=strict_glue_format - ) - elif isinstance(task, MultiRCTask): - _write_multirc_preds( - task, preds_df, pred_dir, split_name, strict_glue_format=strict_glue_format - ) - elif isinstance(task, RTESuperGLUETask): - _write_rte_preds( - task, preds_df, pred_dir, split_name, strict_glue_format=strict_glue_format - ) - elif isinstance(task, ReCoRDTask): - _write_record_preds( - task, preds_df, pred_dir, split_name, strict_glue_format=strict_glue_format - ) - elif isinstance(task, WiCTask): - _write_wic_preds( - task, preds_df, pred_dir, split_name, strict_glue_format=strict_glue_format - ) - elif isinstance(task, WinogradCoreferenceTask): - _write_winograd_preds( - task, preds_df, pred_dir, split_name, strict_glue_format=strict_glue_format - ) - elif isinstance(task, GLUEDiagnosticTask): - # glue-diagnostic is caught above by being in ALL_GLUE_TASKS - # currently this only catches superglue-diagnostic - _write_diagnostics_preds( - task, preds_df, pred_dir, split_name, strict_glue_format=strict_glue_format - ) - elif isinstance(task, QASRLTask): - _write_simple_tsv_preds(task, preds_df, pred_dir, split_name) - else: - log.warning("Task '%s' not supported by write_preds().", task.name) - continue - log.info("Task '%s': Wrote predictions to %s", task.name, pred_dir) - log.info("Wrote all preds for split '%s' to %s", split_name, pred_dir) - return - - -# Exact file names per task required by the GLUE evaluation server -GLUE_NAME_MAP = { - "cola": "CoLA", - "glue-diagnostic": "AX", - "mnli-mm": "MNLI-mm", - "mnli-m": "MNLI-m", - "mrpc": "MRPC", - "qnli": "QNLI", - "qqp": "QQP", - "rte": "RTE", - "sst": "SST-2", - "sts-b": "STS-B", - "wnli": "WNLI", -} - -# Exact file names per task required by the SuperGLUE evaluation server -SUPERGLUE_NAME_MAP = { - "boolq": "BoolQ", - "commitbank": "CB", - "copa": "COPA", - "multirc": "MultiRC", - "record": "ReCoRD", - "rte-superglue": "RTE", - "wic": "WiC", - "winograd-coreference": "WSC", - "broadcoverage-diagnostic": "AX-b", - "winogender-diagnostic": "AX-g", -} - - -def _get_pred_filename(task_name, pred_dir, split_name, strict_glue_format): - if strict_glue_format and task_name in GLUE_NAME_MAP: - if split_name == "test": - file = "%s.tsv" % (GLUE_NAME_MAP[task_name]) - else: - file = "%s_%s.tsv" % (GLUE_NAME_MAP[task_name], split_name) - elif strict_glue_format and task_name in SUPERGLUE_NAME_MAP: - if split_name == "test": - file = "%s.jsonl" % (SUPERGLUE_NAME_MAP[task_name]) - else: - file = "%s_%s.jsonl" % (SUPERGLUE_NAME_MAP[task_name], split_name) - else: - file = "%s_%s.tsv" % (task_name, split_name) - return os.path.join(pred_dir, file) - - -def _write_edge_preds( - task: EdgeProbingTask, - preds_df: pd.DataFrame, - pred_dir: str, - split_name: str, - join_with_input: bool = True, -): - """ Write predictions for edge probing task. - - This reads the task data and joins with predictions, - taking the 'idx' field to represent the line number in the (preprocessed) - task data file. - - Predictions are saved as JSON with one record per line. - """ - preds_file = os.path.join(pred_dir, f"{task.name}_{split_name}.json") - # Each row of 'preds' is a NumPy object, need to convert to list for - # serialization. - preds_df = preds_df.copy() - preds_df["preds"] = [a.tolist() for a in preds_df["preds"]] - if join_with_input: - preds_df.set_index(["idx"], inplace=True) - # Load input data and join by row index. - log.info("Task '%s': joining predictions with input split '%s'", task.name, split_name) - records = task.get_split_text(split_name) - # TODO: update this with more prediction types, when available. - records = ( - task.merge_preds(r, {"proba": preds_df.at[i, "preds"]}) for i, r in enumerate(records) - ) - else: - records = (row.to_dict() for _, row in preds_df.iterrows()) - - with open(preds_file, "w") as fd: - for record in records: - fd.write(json.dumps(record)) - fd.write("\n") - - -def _write_wic_preds( - task: str, - preds_df: pd.DataFrame, - pred_dir: str, - split_name: str, - strict_glue_format: bool = False, -): - """ Write predictions for WiC task. """ - pred_map = {0: "false", 1: "true"} - preds_file = _get_pred_filename(task.name, pred_dir, split_name, strict_glue_format) - with open(preds_file, "w", encoding="utf-8") as preds_fh: - for row_idx, row in preds_df.iterrows(): - if strict_glue_format: - out_d = {"idx": row["idx"], "label": pred_map[row["preds"]]} - else: - out_d = row.to_dict() - preds_fh.write("{0}\n".format(json.dumps(out_d))) - - -def _write_winograd_preds( - task: str, - preds_df: pd.DataFrame, - pred_dir: str, - split_name: str, - strict_glue_format: bool = False, -): - """ Write predictions for Winograd Coreference task. """ - pred_map = {0: "False", 1: "True"} - preds_file = _get_pred_filename(task.name, pred_dir, split_name, strict_glue_format) - with open(preds_file, "w", encoding="utf-8") as preds_fh: - for row_idx, row in preds_df.iterrows(): - if strict_glue_format: - out_d = {"idx": int(row["idx"]), "label": pred_map[row["preds"]]} - else: - out_d = row.to_dict() - preds_fh.write("{0}\n".format(json.dumps(out_d))) - - -def _write_boolq_preds( - task: str, - preds_df: pd.DataFrame, - pred_dir: str, - split_name: str, - strict_glue_format: bool = False, -): - """ Write predictions for Boolean Questions task. """ - pred_map = {0: "false", 1: "true"} - preds_file = _get_pred_filename(task.name, pred_dir, split_name, strict_glue_format) - with open(preds_file, "w", encoding="utf-8") as preds_fh: - for row_idx, row in preds_df.iterrows(): - if strict_glue_format: - out_d = {"idx": int(row["idx"]), "label": pred_map[row["preds"]]} - else: - out_d = row.to_dict() - preds_fh.write("{0}\n".format(json.dumps(out_d))) - - -def _write_commitment_preds( - task: str, - preds_df: pd.DataFrame, - pred_dir: str, - split_name: str, - strict_glue_format: bool = False, -): - """ Write predictions for CommitmentBank task. """ - pred_map = {0: "neutral", 1: "entailment", 2: "contradiction"} - preds_file = _get_pred_filename(task.name, pred_dir, split_name, strict_glue_format) - with open(preds_file, "w", encoding="utf-8") as preds_fh: - for row_idx, row in preds_df.iterrows(): - if strict_glue_format: - out_d = {"idx": row["idx"], "label": pred_map[row["preds"]]} - else: - out_d = row.to_dict() - preds_fh.write("{0}\n".format(json.dumps(out_d))) - - -def _write_copa_preds( - task, preds_df: pd.DataFrame, pred_dir: str, split_name: str, strict_glue_format: bool = False -): - """ Write COPA predictions to JSONL """ - preds_file = _get_pred_filename(task.name, pred_dir, split_name, strict_glue_format) - with open(preds_file, "w", encoding="utf-8") as preds_fh: - for row_idx, row in preds_df.iterrows(): - if strict_glue_format: - out_d = {"idx": int(row["idx"]), "label": int(row["preds"])} - else: - out_d = row.to_dict() - preds_fh.write("{0}\n".format(json.dumps(out_d))) - - -def _write_multirc_preds( - task: str, - preds_df: pd.DataFrame, - pred_dir: str, - split_name: str, - strict_glue_format: bool = False, -): - """ Write predictions for MultiRC task. """ - preds_file = _get_pred_filename(task.name, pred_dir, split_name, strict_glue_format) - with open(preds_file, "w", encoding="utf-8") as preds_fh: - if strict_glue_format: - par_qst_ans_d = defaultdict(lambda: defaultdict(list)) - for row_idx, row in preds_df.iterrows(): - ans_d = {"idx": int(row["ans_idx"]), "label": int(row["preds"])} - par_qst_ans_d[int(row["psg_idx"])][int(row["qst_idx"])].append(ans_d) - for par_idx, qst_ans_d in par_qst_ans_d.items(): - qst_ds = [] - for qst_idx, answers in qst_ans_d.items(): - qst_d = {"idx": qst_idx, "answers": answers} - qst_ds.append(qst_d) - out_d = {"idx": par_idx, "passage": {"questions": qst_ds}} - preds_fh.write("{0}\n".format(json.dumps(out_d))) - else: - for row_idx, row in preds_df.iterrows(): - out_d = row.to_dict() - preds_fh.write("{0}\n".format(json.dumps(out_d))) - - -def _write_record_preds( - task: str, - preds_df: pd.DataFrame, - pred_dir: str, - split_name: str, - strict_glue_format: bool = False, -): - """ Write predictions for ReCoRD task. """ - preds_file = _get_pred_filename(task.name, pred_dir, split_name, strict_glue_format) - with open(preds_file, "w", encoding="utf-8") as preds_fh: - if strict_glue_format: - par_qst_ans_d = defaultdict(lambda: defaultdict(list)) - for row_idx, row in preds_df.iterrows(): - ans_d = { - "idx": int(row["ans_idx"]), - "str": row["ans_str"], - "logit": torch.FloatTensor(row["preds"]), - } - par_qst_ans_d[row["psg_idx"]][row["qst_idx"]].append(ans_d) - for par_idx, qst_ans_d in par_qst_ans_d.items(): - for qst_idx, ans_ds in qst_ans_d.items(): - - # get prediction - logits_and_anss = [(d["logit"], d["str"]) for d in ans_ds] - logits_and_anss.sort(key=lambda x: x[1]) - logits, anss = list(zip(*logits_and_anss)) - pred_idx = torch.softmax(torch.stack(logits), dim=-1)[:, -1].argmax().item() - answer = anss[pred_idx] - - # write out answer - qst_d = {"idx": qst_idx, "label": answer} - preds_fh.write("{0}\n".format(json.dumps(qst_d))) - else: - for row_idx, row in preds_df.iterrows(): - out_d = row.to_dict() - preds_fh.write("{0}\n".format(json.dumps(out_d))) - - -def _write_rte_preds( - task: str, - preds_df: pd.DataFrame, - pred_dir: str, - split_name: str, - strict_glue_format: bool = False, -): - """ Write predictions for RTE task in SuperGLUE prediction format. """ - trg_map = {0: "not_entailment", 1: "entailment"} - preds_file = _get_pred_filename(task.name, pred_dir, split_name, strict_glue_format) - with open(preds_file, "w", encoding="utf-8") as preds_fh: - for row_idx, row in preds_df.iterrows(): - if strict_glue_format: - out_d = {"idx": row["idx"], "label": trg_map[row["preds"]]} - else: - out_d = row.to_dict() - preds_fh.write("{0}\n".format(json.dumps(out_d))) - - -def _write_simple_tsv_preds(task, preds_df: pd.DataFrame, pred_dir: str, split_name: str): - preds_file = _get_pred_filename(task.name, pred_dir, split_name, strict_glue_format=False) - preds_df.to_csv(preds_file, sep="\t") - - -def _write_diagnostics_preds( - task: str, - preds_df: pd.DataFrame, - pred_dir: str, - split_name: str, - strict_glue_format: bool = False, -): - """ Write predictions for GLUE/SuperGLUE diagnostics task. """ - - if task.n_classes == 2: - pred_map = {0: "not_entailment", 1: "entailment"} - elif task.n_classes == 3: - pred_map = {0: "neutral", 1: "entailment", 2: "contradiction"} - else: - raise ValueError("Invalid number of output classes detected") - - preds_file = _get_pred_filename(task.name, pred_dir, split_name, strict_glue_format) - with open(preds_file, "w", encoding="utf-8") as preds_fh: - for row_idx, row in preds_df.iterrows(): - if strict_glue_format: - out_d = {"idx": row["idx"], "label": pred_map[row["preds"]]} - else: - out_d = row.to_dict() - preds_fh.write("{0}\n".format(json.dumps(out_d))) - - -def _write_glue_preds( - task_name: str, - preds_df: pd.DataFrame, - pred_dir: str, - split_name: str, - strict_glue_format: bool = False, -): - """ Write predictions to separate files located in pred_dir. - We write special code to handle various GLUE tasks. - - Use strict_glue_format to guarantee compatibility with GLUE website. - - Args: - task_name: task name - preds_df: predictions DataFrame for a single task, as returned by - evaluate(). - pred_dir: directory to write predictions - split_name: name of this split ('train', 'val', or 'test') - strict_glue_format: if true, writes format compatible with GLUE - website. - """ - - def _apply_pred_map(preds_df, pred_map, key="prediction"): - """ Apply preds_map, in-place. """ - preds_df[key] = [pred_map[p] for p in preds_df[key]] - - def _write_preds_with_pd(preds_df: pd.DataFrame, pred_file: str, write_type=int): - """ Write TSV file in GLUE format, using Pandas. """ - - required_cols = ["index", "prediction"] - if strict_glue_format: - cols_to_write = required_cols - quoting = QUOTE_NONE - log.info( - "Task '%s', split '%s': writing %s in " "strict GLUE format.", - task_name, - split_name, - pred_file, - ) - else: - all_cols = set(preds_df.columns) - # make sure we write index and prediction as first columns, - # then all the other ones we can find. - cols_to_write = required_cols + sorted(list(all_cols.difference(required_cols))) - quoting = QUOTE_MINIMAL - preds_df.to_csv( - pred_file, - sep="\t", - index=False, - float_format="%.3f", - quoting=quoting, - columns=cols_to_write, - ) - - if len(preds_df) == 0: # catch empty lists - log.warning("Task '%s': predictions are empty!", task_name) - return - - def _add_default_column(df, name: str, val): - """ Ensure column exists and missing values = val. """ - if name not in df: - df[name] = val - df[name].fillna(value=val, inplace=True) - - preds_df = preds_df.copy() - _add_default_column(preds_df, "idx", -1) - _add_default_column(preds_df, "sent1_str", "") - _add_default_column(preds_df, "sent2_str", "") - _add_default_column(preds_df, "labels", -1) - # Rename columns to match output headers. - preds_df.rename( - { - "idx": "index", - "preds": "prediction", - "sent1_str": "sentence_1", - "sent2_str": "sentence_2", - "labels": "true_label", - }, - axis="columns", - inplace=True, - ) - - if task_name == "mnli" and split_name == "test": # 9796 + 9847 = 19643 - assert len(preds_df) == 19643, "Missing predictions for MNLI!" - log.info("There are %d examples in MNLI, 19643 were expected", len(preds_df)) - # Sort back to original order to split matched and mismatched, which are - # treated as a single dataset by jiant. - preds_df.sort_index(inplace=True) - pred_map = {0: "neutral", 1: "entailment", 2: "contradiction"} - _apply_pred_map(preds_df, pred_map, "prediction") - _write_preds_with_pd( - preds_df.iloc[:9796], - _get_pred_filename("mnli-m", pred_dir, split_name, strict_glue_format), - ) - _write_preds_with_pd( - preds_df.iloc[9796:], - _get_pred_filename("mnli-mm", pred_dir, split_name, strict_glue_format), - ) - elif task_name in ["rte", "qnli"]: - pred_map = {0: "not_entailment", 1: "entailment"} - _apply_pred_map(preds_df, pred_map, "prediction") - _write_preds_with_pd( - preds_df, _get_pred_filename(task_name, pred_dir, split_name, strict_glue_format) - ) - elif task_name in ["sts-b"]: - preds_df["prediction"] = [min(max(0.0, pred * 5.0), 5.0) for pred in preds_df["prediction"]] - _write_preds_with_pd( - preds_df, - _get_pred_filename(task_name, pred_dir, split_name, strict_glue_format), - write_type=float, - ) - elif task_name in ["wmt"]: - # convert each prediction to a single string if we find a list of - # tokens - if isinstance(preds_df["prediction"][0], list): - assert isinstance(preds_df["prediction"][0][0], str) - preds_df["prediction"] = [" ".join(pred) for pred in preds_df["prediction"]] - _write_preds_with_pd( - preds_df, - _get_pred_filename(task_name, pred_dir, split_name, strict_glue_format), - write_type=str, - ) - else: - _write_preds_with_pd( - preds_df, - _get_pred_filename(task_name, pred_dir, split_name, strict_glue_format), - write_type=int, - ) - - log.info("Wrote predictions for task: %s", task_name) - - -def write_results(results, results_file, run_name): - """ Aggregate results by appending results to results_file """ - all_metrics_str = ", ".join(["%s: %.3f" % (metric, score) for metric, score in results.items()]) - with open(results_file, "a") as results_fh: - results_fh.write("%s\t%s\n" % (run_name, all_metrics_str)) - log.info(all_metrics_str) diff --git a/jiant/allennlp_mods/__init__.py b/jiant/ext/__init__.py similarity index 100% rename from jiant/allennlp_mods/__init__.py rename to jiant/ext/__init__.py diff --git a/jiant/ext/allennlp.py b/jiant/ext/allennlp.py new file mode 100644 index 000000000..e4616b5b1 --- /dev/null +++ b/jiant/ext/allennlp.py @@ -0,0 +1,337 @@ +from typing import Optional + +import torch +import torch.nn as nn + + +# noinspection PyTypeChecker +# noinspection PyUnusedLocal +class SelfAttentiveSpanExtractor(nn.Module): + """ + Computes span representations by generating an unnormalized attention score for each + word in the document. Spans representations are computed with respect to these + scores by normalising the attention scores for words inside the span. + + Given these attention distributions over every span, this module weights the + corresponding vector representations of the words in the span by this distribution, + returning a weighted representation of each span. + + Parameters + ---------- + input_dim : ``int``, required. + The final dimension of the ``sequence_tensor``. + + Returns + ------- + attended_text_embeddings : ``torch.FloatTensor``. + A tensor of shape (batch_size, num_spans, input_dim), which each span representation + is formed by locally normalising a global attention over the sequence. The only way + in which the attention distribution differs over different spans is in the set of words + over which they are normalized. + """ + + def __init__(self, input_dim: int) -> None: + super().__init__() + self._input_dim = input_dim + self._global_attention = TimeDistributed(torch.nn.Linear(input_dim, 1)) + + def get_input_dim(self) -> int: + return self._input_dim + + def get_output_dim(self) -> int: + return self._input_dim + + def forward( + self, + sequence_tensor: torch.FloatTensor, + span_indices: torch.LongTensor, + sequence_mask: torch.LongTensor = None, + span_indices_mask: torch.LongTensor = None, + ) -> torch.FloatTensor: + # both of shape (batch_size, num_spans, 1) + span_starts, span_ends = span_indices.split(1, dim=-1) + + # shape (batch_size, num_spans, 1) + # These span widths are off by 1, because the span ends are `inclusive`. + span_widths = span_ends - span_starts + + # We need to know the maximum span width so we can + # generate indices to extract the spans from the sequence tensor. + # These indices will then get masked below, such that if the length + # of a given span is smaller than the max, the rest of the values + # are masked. + max_batch_span_width = span_widths.max().item() + 1 + + # shape (batch_size, sequence_length, 1) + global_attention_logits = self._global_attention(sequence_tensor) + + # Shape: (1, 1, max_batch_span_width) + max_span_range_indices = get_range_vector( + max_batch_span_width, get_device_of(sequence_tensor) + ).view(1, 1, -1) + # Shape: (batch_size, num_spans, max_batch_span_width) + # This is a broadcasted comparison - for each span we are considering, + # we are creating a range vector of size max_span_width, but masking values + # which are greater than the actual length of the span. + # + # We're using <= here (and for the mask below) because the span ends are + # inclusive, so we want to include indices which are equal to span_widths rather + # than using it as a non-inclusive upper bound. + span_mask = (max_span_range_indices <= span_widths).float() + raw_span_indices = span_ends - max_span_range_indices + # We also don't want to include span indices which are less than zero, + # which happens because some spans near the beginning of the sequence + # have an end index < max_batch_span_width, so we add this to the mask here. + span_mask = span_mask * (raw_span_indices >= 0).float() + span_indices = torch.nn.functional.relu(raw_span_indices.float()).long() + + # Shape: (batch_size * num_spans * max_batch_span_width) + flat_span_indices = flatten_and_batch_shift_indices(span_indices, sequence_tensor.size(1)) + + # Shape: (batch_size, num_spans, max_batch_span_width, embedding_dim) + span_embeddings = batched_index_select(sequence_tensor, span_indices, flat_span_indices) + + # Shape: (batch_size, num_spans, max_batch_span_width) + span_attention_logits = batched_index_select( + global_attention_logits, span_indices, flat_span_indices + ).squeeze(-1) + # Shape: (batch_size, num_spans, max_batch_span_width) + span_attention_weights = masked_softmax(span_attention_logits, span_mask) + + # Do a weighted sum of the embedded spans with + # respect to the normalised attention distributions. + # Shape: (batch_size, num_spans, embedding_dim) + attended_text_embeddings = weighted_sum(span_embeddings, span_attention_weights) + + if span_indices_mask is not None: + # Above we were masking the widths of spans with respect to the max + # span width in the batch. Here we are masking the spans which were + # originally passed in as padding. + return attended_text_embeddings * span_indices_mask.unsqueeze(-1).float() + + return attended_text_embeddings + + +class TimeDistributed(torch.nn.Module): + """ + Given an input shaped like ``(batch_size, time_steps, [rest])`` and a ``Module`` that takes + inputs like ``(batch_size, [rest])``, ``TimeDistributed`` reshapes the input to be + ``(batch_size * time_steps, [rest])``, applies the contained ``Module``, then reshapes it back. + + Note that while the above gives shapes with ``batch_size`` first, this ``Module`` also works if + ``batch_size`` is second - we always just combine the first two dimensions, then split them. + """ + + def __init__(self, module): + super(TimeDistributed, self).__init__() + self._module = module + + def forward(self, *inputs): # pylint: disable=arguments-differ + reshaped_inputs = [] + for input_tensor in inputs: + input_size = input_tensor.size() + if len(input_size) <= 2: + raise RuntimeError("No dimension to distribute: " + str(input_size)) + + # Squash batch_size and time_steps into a single axis; result has shape + # (batch_size * time_steps, input_size). + squashed_shape = [-1] + [x for x in input_size[2:]] + reshaped_inputs.append(input_tensor.contiguous().view(*squashed_shape)) + + reshaped_outputs = self._module(*reshaped_inputs) + + # Now get the output back into the right shape. + # (batch_size, time_steps, [hidden_size]) + # noinspection PyUnboundLocalVariable + new_shape = [input_size[0], input_size[1]] + [x for x in reshaped_outputs.size()[1:]] + outputs = reshaped_outputs.contiguous().view(*new_shape) + + return outputs + + +def weighted_sum(matrix: torch.Tensor, attention: torch.Tensor) -> torch.Tensor: + """ + Takes a matrix of vectors and a set of weights over the rows in the matrix (which we call an + "attention" vector), and returns a weighted sum of the rows in the matrix. This is the typical + computation performed after an attention mechanism. + + Note that while we call this a "matrix" of vectors and an attention "vector", we also handle + higher-order tensors. We always sum over the second-to-last dimension of the "matrix", and we + assume that all dimensions in the "matrix" prior to the last dimension are matched in the + "vector". Non-matched dimensions in the "vector" must be `directly after the batch dimension`. + + For example, say I have a "matrix" with dimensions ``(batch_size, num_queries, num_words, + embedding_dim)``. The attention "vector" then must have at least those dimensions, and could + have more. Both: + + - ``(batch_size, num_queries, num_words)`` (distribution over words for each query) + - ``(batch_size, num_documents, num_queries, num_words)`` (distribution over words in a + query for each document) + + are valid input "vectors", producing tensors of shape: + ``(batch_size, num_queries, embedding_dim)`` and + ``(batch_size, num_documents, num_queries, embedding_dim)`` respectively. + """ + # We'll special-case a few settings here, where there are efficient (but poorly-named) + # operations in pytorch that already do the computation we need. + if attention.dim() == 2 and matrix.dim() == 3: + return attention.unsqueeze(1).bmm(matrix).squeeze(1) + if attention.dim() == 3 and matrix.dim() == 3: + return attention.bmm(matrix) + if matrix.dim() - 1 < attention.dim(): + expanded_size = list(matrix.size()) + for i in range(attention.dim() - matrix.dim() + 1): + matrix = matrix.unsqueeze(1) + expanded_size.insert(i + 1, attention.size(i + 1)) + matrix = matrix.expand(*expanded_size) + intermediate = attention.unsqueeze(-1).expand_as(matrix) * matrix + return intermediate.sum(dim=-2) + + +def masked_softmax(vector: torch.Tensor, mask: torch.Tensor, dim: int = -1) -> torch.Tensor: + """ + ``torch.nn.functional.softmax(vector)`` does not work if some elements of ``vector`` should be + masked. This performs a softmax on just the non-masked portions of ``vector``. Passing + ``None`` in for the mask is also acceptable; you'll just get a regular softmax. + + ``vector`` can have an arbitrary number of dimensions; the only requirement is that ``mask`` is + broadcastable to ``vector's`` shape. If ``mask`` has fewer dimensions than ``vector``, we will + unsqueeze on dimension 1 until they match. If you need a different unsqueezing of your mask, + do it yourself before passing the mask into this function. + + In the case that the input vector is completely masked, this function returns an array + of ``0.0``. This behavior may cause ``NaN`` if this is used as the last layer of a model + that uses categorical cross-entropy loss. + """ + if mask is None: + result = torch.nn.functional.softmax(vector, dim=dim) + else: + mask = mask.float() + while mask.dim() < vector.dim(): + mask = mask.unsqueeze(1) + # To limit numerical errors from large vector elements outside the mask, we zero these out. + result = torch.nn.functional.softmax(vector * mask, dim=dim) + result = result * mask + result = result / (result.sum(dim=dim, keepdim=True) + 1e-13) + return result + + +def batched_index_select( + target: torch.Tensor, + indices: torch.LongTensor, + flattened_indices: Optional[torch.LongTensor] = None, +) -> torch.Tensor: + """ + The given ``indices`` of size ``(batch_size, d_1, ..., d_n)`` indexes into the sequence + dimension (dimension 2) of the target, which has size ``(batch_size, sequence_length, + embedding_size)``. + + This function returns selected values in the target with respect to the provided indices, which + have size ``(batch_size, d_1, ..., d_n, embedding_size)``. This can use the optionally + precomputed :func:`~flattened_indices` with size ``(batch_size * d_1 * ... * d_n)`` if given. + + An example use case of this function is looking up the start and end indices of spans in a + sequence tensor. This is used in the + :class:`~allennlp.models.coreference_resolution.CoreferenceResolver`. Model to select + contextual word representations corresponding to the start and end indices of mentions. The key + reason this can't be done with basic torch functions is that we want to be able to use look-up + tensors with an arbitrary number of dimensions (for example, in the coref model, we don't know + a-priori how many spans we are looking up). + + Parameters + ---------- + target : ``torch.Tensor``, required. + A 3 dimensional tensor of shape (batch_size, sequence_length, embedding_size). + This is the tensor to be indexed. + indices : ``torch.LongTensor`` + A tensor of shape (batch_size, ...), where each element is an index into the + ``sequence_length`` dimension of the ``target`` tensor. + flattened_indices : Optional[torch.Tensor], optional (default = None) + An optional tensor representing the result of calling :func:~`flatten_and_batch_shift_indices` + on ``indices``. This is helpful in the case that the indices can be flattened once and + cached for many batch lookups. + + Returns + ------- + selected_targets : ``torch.Tensor`` + A tensor with shape [indices.size(), target.size(-1)] representing the embedded indices + extracted from the batch flattened target tensor. + """ + if flattened_indices is None: + # Shape: (batch_size * d_1 * ... * d_n) + flattened_indices = flatten_and_batch_shift_indices(indices, target.size(1)) + + # Shape: (batch_size * sequence_length, embedding_size) + flattened_target = target.view(-1, target.size(-1)) + + # Shape: (batch_size * d_1 * ... * d_n, embedding_size) + flattened_selected = flattened_target.index_select(0, flattened_indices) + selected_shape = list(indices.size()) + [target.size(-1)] + # Shape: (batch_size, d_1, ..., d_n, embedding_size) + selected_targets = flattened_selected.view(*selected_shape) + return selected_targets + + +def flatten_and_batch_shift_indices(indices: torch.Tensor, sequence_length: int) -> torch.Tensor: + """ + This is a subroutine for :func:`~batched_index_select`. The given ``indices`` of size + ``(batch_size, d_1, ..., d_n)`` indexes into dimension 2 of a target tensor, which has size + ``(batch_size, sequence_length, embedding_size)``. This function returns a vector that + correctly indexes into the flattened target. The sequence length of the target must be + provided to compute the appropriate offsets. + + .. code-block:: python + + indices = torch.ones([2,3], dtype=torch.long) + # Sequence length of the target tensor. + sequence_length = 10 + shifted_indices = flatten_and_batch_shift_indices(indices, sequence_length) + # Indices into the second element in the batch are correctly shifted + # to take into account that the target tensor will be flattened before + # the indices are applied. + assert shifted_indices == [1, 1, 1, 11, 11, 11] + + Parameters + ---------- + indices : ``torch.LongTensor``, required. + sequence_length : ``int``, required. + The length of the sequence the indices index into. + This must be the second dimension of the tensor. + + Returns + ------- + offset_indices : ``torch.LongTensor`` + """ + # Shape: (batch_size) + offsets = get_range_vector(indices.size(0), get_device_of(indices)) * sequence_length + for _ in range(len(indices.size()) - 1): + offsets = offsets.unsqueeze(1) + + # Shape: (batch_size, d_1, ..., d_n) + offset_indices = indices + offsets + + # Shape: (batch_size * d_1 * ... * d_n) + offset_indices = offset_indices.view(-1) + return offset_indices + + +# noinspection PyUnresolvedReferences +def get_range_vector(size: int, device: int) -> torch.Tensor: + """ + Returns a range vector with the desired size, starting at 0. The CUDA implementation + is meant to avoid copy data from CPU to GPU. + """ + if device > -1: + return torch.cuda.LongTensor(size, device=device).fill_(1).cumsum(0) - 1 + else: + return torch.arange(0, size, dtype=torch.long) + + +def get_device_of(tensor: torch.Tensor) -> int: + """ + Returns the device of the tensor. + """ + if not tensor.is_cuda: + return -1 + else: + return tensor.get_device() diff --git a/jiant/ext/radam.py b/jiant/ext/radam.py new file mode 100644 index 000000000..52fb93dcb --- /dev/null +++ b/jiant/ext/radam.py @@ -0,0 +1,277 @@ +import math +import torch +from torch.optim.optimizer import Optimizer + + +# noinspection PyPep8Naming +class RAdam(Optimizer): + def __init__( + self, params, lr=1e-3, betas=(0.9, 0.999), eps=1e-8, weight_decay=0, degenerated_to_sgd=True + ): + if not 0.0 <= lr: + raise ValueError("Invalid learning rate: {}".format(lr)) + if not 0.0 <= eps: + raise ValueError("Invalid epsilon value: {}".format(eps)) + if not 0.0 <= betas[0] < 1.0: + raise ValueError("Invalid beta parameter at index 0: {}".format(betas[0])) + if not 0.0 <= betas[1] < 1.0: + raise ValueError("Invalid beta parameter at index 1: {}".format(betas[1])) + + self.degenerated_to_sgd = degenerated_to_sgd + if isinstance(params, (list, tuple)) and len(params) > 0 and isinstance(params[0], dict): + for param in params: + if "betas" in param and ( + param["betas"][0] != betas[0] or param["betas"][1] != betas[1] + ): + param["buffer"] = [[None, None, None] for _ in range(10)] + defaults = dict( + lr=lr, + betas=betas, + eps=eps, + weight_decay=weight_decay, + buffer=[[None, None, None] for _ in range(10)], + ) + super(RAdam, self).__init__(params, defaults) + + def __setstate__(self, state): + super(RAdam, self).__setstate__(state) + + def step(self, closure=None): + + loss = None + if closure is not None: + loss = closure() + + for group in self.param_groups: + + for p in group["params"]: + if p.grad is None: + continue + grad = p.grad.data.float() + if grad.is_sparse: + raise RuntimeError("RAdam does not support sparse gradients") + + p_data_fp32 = p.data.float() + + state = self.state[p] + + if len(state) == 0: + state["step"] = 0 + state["exp_avg"] = torch.zeros_like(p_data_fp32) + state["exp_avg_sq"] = torch.zeros_like(p_data_fp32) + else: + state["exp_avg"] = state["exp_avg"].type_as(p_data_fp32) + state["exp_avg_sq"] = state["exp_avg_sq"].type_as(p_data_fp32) + + exp_avg, exp_avg_sq = state["exp_avg"], state["exp_avg_sq"] + beta1, beta2 = group["betas"] + + exp_avg_sq.mul_(beta2).addcmul_(1 - beta2, grad, grad) + exp_avg.mul_(beta1).add_(1 - beta1, grad) + + state["step"] += 1 + buffered = group["buffer"][int(state["step"] % 10)] + if state["step"] == buffered[0]: + N_sma, step_size = buffered[1], buffered[2] + else: + buffered[0] = state["step"] + beta2_t = beta2 ** state["step"] + N_sma_max = 2 / (1 - beta2) - 1 + N_sma = N_sma_max - 2 * state["step"] * beta2_t / (1 - beta2_t) + buffered[1] = N_sma + + # more conservative since it's an approximated value + if N_sma >= 5: + step_size = math.sqrt( + (1 - beta2_t) + * (N_sma - 4) + / (N_sma_max - 4) + * (N_sma - 2) + / N_sma + * N_sma_max + / (N_sma_max - 2) + ) / (1 - beta1 ** state["step"]) + elif self.degenerated_to_sgd: + step_size = 1.0 / (1 - beta1 ** state["step"]) + else: + step_size = -1 + buffered[2] = step_size + + # more conservative since it's an approximated value + if N_sma >= 5: + if group["weight_decay"] != 0: + p_data_fp32.add_(-group["weight_decay"] * group["lr"], p_data_fp32) + denom = exp_avg_sq.sqrt().add_(group["eps"]) + p_data_fp32.addcdiv_(-step_size * group["lr"], exp_avg, denom) + p.data.copy_(p_data_fp32) + elif step_size > 0: + if group["weight_decay"] != 0: + p_data_fp32.add_(-group["weight_decay"] * group["lr"], p_data_fp32) + p_data_fp32.add_(-step_size * group["lr"], exp_avg) + p.data.copy_(p_data_fp32) + + return loss + + +# noinspection PyPep8Naming +class PlainRAdam(Optimizer): + def __init__( + self, params, lr=1e-3, betas=(0.9, 0.999), eps=1e-8, weight_decay=0, degenerated_to_sgd=True + ): + if not 0.0 <= lr: + raise ValueError("Invalid learning rate: {}".format(lr)) + if not 0.0 <= eps: + raise ValueError("Invalid epsilon value: {}".format(eps)) + if not 0.0 <= betas[0] < 1.0: + raise ValueError("Invalid beta parameter at index 0: {}".format(betas[0])) + if not 0.0 <= betas[1] < 1.0: + raise ValueError("Invalid beta parameter at index 1: {}".format(betas[1])) + + self.degenerated_to_sgd = degenerated_to_sgd + defaults = dict(lr=lr, betas=betas, eps=eps, weight_decay=weight_decay) + + super(PlainRAdam, self).__init__(params, defaults) + + def __setstate__(self, state): + super(PlainRAdam, self).__setstate__(state) + + def step(self, closure=None): + + loss = None + if closure is not None: + loss = closure() + + for group in self.param_groups: + + for p in group["params"]: + if p.grad is None: + continue + grad = p.grad.data.float() + if grad.is_sparse: + raise RuntimeError("RAdam does not support sparse gradients") + + p_data_fp32 = p.data.float() + + state = self.state[p] + + if len(state) == 0: + state["step"] = 0 + state["exp_avg"] = torch.zeros_like(p_data_fp32) + state["exp_avg_sq"] = torch.zeros_like(p_data_fp32) + else: + state["exp_avg"] = state["exp_avg"].type_as(p_data_fp32) + state["exp_avg_sq"] = state["exp_avg_sq"].type_as(p_data_fp32) + + exp_avg, exp_avg_sq = state["exp_avg"], state["exp_avg_sq"] + beta1, beta2 = group["betas"] + + exp_avg_sq.mul_(beta2).addcmul_(1 - beta2, grad, grad) + exp_avg.mul_(beta1).add_(1 - beta1, grad) + + state["step"] += 1 + beta2_t = beta2 ** state["step"] + N_sma_max = 2 / (1 - beta2) - 1 + N_sma = N_sma_max - 2 * state["step"] * beta2_t / (1 - beta2_t) + + # more conservative since it's an approximated value + if N_sma >= 5: + if group["weight_decay"] != 0: + p_data_fp32.add_(-group["weight_decay"] * group["lr"], p_data_fp32) + step_size = ( + group["lr"] + * math.sqrt( + (1 - beta2_t) + * (N_sma - 4) + / (N_sma_max - 4) + * (N_sma - 2) + / N_sma + * N_sma_max + / (N_sma_max - 2) + ) + / (1 - beta1 ** state["step"]) + ) + denom = exp_avg_sq.sqrt().add_(group["eps"]) + p_data_fp32.addcdiv_(-step_size, exp_avg, denom) + p.data.copy_(p_data_fp32) + elif self.degenerated_to_sgd: + if group["weight_decay"] != 0: + p_data_fp32.add_(-group["weight_decay"] * group["lr"], p_data_fp32) + step_size = group["lr"] / (1 - beta1 ** state["step"]) + p_data_fp32.add_(-step_size, exp_avg) + p.data.copy_(p_data_fp32) + + return loss + + +class AdamW(Optimizer): + def __init__(self, params, lr=1e-3, betas=(0.9, 0.999), eps=1e-8, weight_decay=0, warmup=0): + if not 0.0 <= lr: + raise ValueError("Invalid learning rate: {}".format(lr)) + if not 0.0 <= eps: + raise ValueError("Invalid epsilon value: {}".format(eps)) + if not 0.0 <= betas[0] < 1.0: + raise ValueError("Invalid beta parameter at index 0: {}".format(betas[0])) + if not 0.0 <= betas[1] < 1.0: + raise ValueError("Invalid beta parameter at index 1: {}".format(betas[1])) + + defaults = dict(lr=lr, betas=betas, eps=eps, weight_decay=weight_decay, warmup=warmup) + super(AdamW, self).__init__(params, defaults) + + def __setstate__(self, state): + super(AdamW, self).__setstate__(state) + + def step(self, closure=None): + loss = None + if closure is not None: + loss = closure() + + for group in self.param_groups: + + for p in group["params"]: + if p.grad is None: + continue + grad = p.grad.data.float() + if grad.is_sparse: + raise RuntimeError( + "Adam does not support sparse gradients, please consider SparseAdam instead" + ) + + p_data_fp32 = p.data.float() + + state = self.state[p] + + if len(state) == 0: + state["step"] = 0 + state["exp_avg"] = torch.zeros_like(p_data_fp32) + state["exp_avg_sq"] = torch.zeros_like(p_data_fp32) + else: + state["exp_avg"] = state["exp_avg"].type_as(p_data_fp32) + state["exp_avg_sq"] = state["exp_avg_sq"].type_as(p_data_fp32) + + exp_avg, exp_avg_sq = state["exp_avg"], state["exp_avg_sq"] + beta1, beta2 = group["betas"] + + state["step"] += 1 + + exp_avg_sq.mul_(beta2).addcmul_(1 - beta2, grad, grad) + exp_avg.mul_(beta1).add_(1 - beta1, grad) + + denom = exp_avg_sq.sqrt().add_(group["eps"]) + bias_correction1 = 1 - beta1 ** state["step"] + bias_correction2 = 1 - beta2 ** state["step"] + + if group["warmup"] > state["step"]: + scheduled_lr = 1e-8 + state["step"] * group["lr"] / group["warmup"] + else: + scheduled_lr = group["lr"] + + step_size = scheduled_lr * math.sqrt(bias_correction2) / bias_correction1 + + if group["weight_decay"] != 0: + p_data_fp32.add_(-group["weight_decay"] * scheduled_lr, p_data_fp32) + + p_data_fp32.addcdiv_(-step_size, exp_avg, denom) + + p.data.copy_(p_data_fp32) + + return loss diff --git a/jiant/huggingface_transformers_interface/__init__.py b/jiant/huggingface_transformers_interface/__init__.py deleted file mode 100644 index 153b8b714..000000000 --- a/jiant/huggingface_transformers_interface/__init__.py +++ /dev/null @@ -1,68 +0,0 @@ -""" -Warning: jiant currently depends on *both* pytorch_pretrained_bert > 0.6 _and_ -transformers > 2.3 - -These are the same package, though the name changed between these two versions. AllenNLP requires -0.6 to support the BertAdam optimizer, and jiant directly requires 2.3. - -This AllenNLP issue is relevant: https://github.com/allenai/allennlp/issues/3067 - -TODO: We do not support non-English versions of XLM, if you need them, add some code in XLMEmbedderModule -to prepare langs input to transformers.XLMModel -""" - -# All the supported input_module from huggingface transformers -# input_modules mapped to the same string share vocabulary -transformer_input_module_to_tokenizer_name = { - "bert-base-uncased": "bert_uncased", - "bert-large-uncased": "bert_uncased", - "bert-large-uncased-whole-word-masking": "bert_uncased", - "bert-large-uncased-whole-word-masking-finetuned-squad": "bert_uncased", - "bert-base-cased": "bert_cased", - "bert-large-cased": "bert_cased", - "bert-large-cased-whole-word-masking": "bert_cased", - "bert-large-cased-whole-word-masking-finetuned-squad": "bert_cased", - "bert-base-cased-finetuned-mrpc": "bert_cased", - "bert-base-multilingual-uncased": "bert_multilingual_uncased", - "bert-base-multilingual-cased": "bert_multilingual_cased", - "roberta-base": "roberta", - "roberta-large": "roberta", - "roberta-large-mnli": "roberta", - "nyu-mll/roberta-base-100M-1": "roberta", - "nyu-mll/roberta-base-100M-2": "roberta", - "nyu-mll/roberta-base-100M-3": "roberta", - "nyu-mll/roberta-base-10M-1": "roberta", - "nyu-mll/roberta-base-10M-2": "roberta", - "nyu-mll/roberta-base-10M-3": "roberta", - "nyu-mll/roberta-base-1B-1": "roberta", - "nyu-mll/roberta-base-1B-2": "roberta", - "nyu-mll/roberta-base-1B-3": "roberta", - "nyu-mll/roberta-med-small-1M-1": "roberta", - "nyu-mll/roberta-med-small-1M-2": "roberta", - "nyu-mll/roberta-med-small-1M-3": "roberta", - "xlnet-base-cased": "xlnet_cased", - "xlnet-large-cased": "xlnet_cased", - "openai-gpt": "openai_gpt", - "gpt2": "gpt2", - "gpt2-medium": "gpt2", - "gpt2-large": "gpt2", - "gpt2-xl": "gpt2", - "transfo-xl-wt103": "transfo_xl", - "xlm-mlm-en-2048": "xlm_en", - "albert-base-v1": "albert", - "albert-large-v1": "albert", - "albert-xlarge-v1": "albert", - "albert-xxlarge-v1": "albert", - "albert-base-v2": "albert", - "albert-large-v2": "albert", - "albert-xlarge-v2": "albert", - "albert-xxlarge-v2": "albert", -} - - -def input_module_uses_transformers(input_module): - return input_module in transformer_input_module_to_tokenizer_name - - -def input_module_tokenizer_name(input_module): - return transformer_input_module_to_tokenizer_name[input_module] diff --git a/jiant/huggingface_transformers_interface/modules.py b/jiant/huggingface_transformers_interface/modules.py deleted file mode 100644 index 3939120af..000000000 --- a/jiant/huggingface_transformers_interface/modules.py +++ /dev/null @@ -1,732 +0,0 @@ -import copy -import logging as log -import os -from typing import Dict - -import torch -import torch.nn as nn -from allennlp.modules import scalar_mix - -import transformers - -from jiant.utils.options import parse_task_list_arg -from jiant.utils import utils -from jiant.huggingface_transformers_interface import input_module_tokenizer_name - - -class HuggingfaceTransformersEmbedderModule(nn.Module): - """ Shared code for transformers wrappers. - - Subclasses share a good deal of code, but have a number of subtle differences due to different - APIs from transfromers. - """ - - def __init__(self, args): - super(HuggingfaceTransformersEmbedderModule, self).__init__() - - self.cache_dir = os.getenv( - "HUGGINGFACE_TRANSFORMERS_CACHE", os.path.join(args.exp_dir, "transformers_cache") - ) - utils.maybe_make_dir(self.cache_dir) - - self.output_mode = args.transformers_output_mode - self.input_module = args.input_module - self.max_pos = None - self.tokenizer_required = input_module_tokenizer_name(args.input_module) - - # Integer token indices for special symbols. - self._cls_id = None - self._sep_id = None - self._pad_id = None - self._unk_id = None - self._mask_id = None - - # If set, treat these special tokens as part of input segments other than A/B. - self._SEG_ID_CLS = None - self._SEG_ID_SEP = None - - def parameter_setup(self, args): - # Set trainability of this module. - for param in self.model.parameters(): - param.requires_grad = bool(args.transfer_paradigm == "finetune") - - self.num_layers = self.model.config.num_hidden_layers - if args.transformers_max_layer >= 0: - self.max_layer = args.transformers_max_layer - assert self.max_layer <= self.num_layers - else: - self.max_layer = self.num_layers - - if args.transfer_paradigm == "frozen": - if isinstance( - self, (OpenAIGPTEmbedderModule, GPT2EmbedderModule, TransfoXLEmbedderModule) - ): - log.warning( - "NOTE: OpenAI GPT, GPT-2 and Transformer-XL add new tokens for classification" - "tasks, under 'frozen' transfer_paradigm, their embeddings will not be trained" - ) - - # Configure scalar mixing, ELMo-style. - if self.output_mode == "mix": - if args.transfer_paradigm == "frozen": - log.warning( - "NOTE: transformers_output_mode='mix', so scalar " - "mixing weights will be fine-tuned even if BERT " - "model is frozen." - ) - # TODO: if doing multiple target tasks, allow for multiple sets of - # scalars. See the ELMo implementation here: - # https://github.com/allenai/allennlp/blob/master/allennlp/modules/elmo.py#L115 - assert len(parse_task_list_arg(args.target_tasks)) <= 1, ( - "transformers_output_mode='mix' only supports a single set of " - "scalars (but if you need this feature, see the TODO in " - "the code!)" - ) - # Always have one more mixing weight, for lexical layer. - self.scalar_mix = scalar_mix.ScalarMix(self.max_layer + 1, do_layer_norm=False) - - def correct_sent_indexing(self, sent): - """ Correct id difference between transformers and AllenNLP. - The AllenNLP indexer adds'@@UNKNOWN@@' token as index 1, and '@@PADDING@@' as index 0 - - args: - sent: batch dictionary, in which - sent[self.tokenizer_required]: [batch_size, var_seq_len] input token IDs - - returns: - ids: [bath_size, var_seq_len] corrected token IDs - input_mask: [bath_size, var_seq_len] mask of input sequence - """ - assert ( - self.tokenizer_required in sent - ), "transformers cannot find correcpondingly tokenized input" - ids = sent[self.tokenizer_required] - - input_mask = (ids != 0).long() - pad_mask = (ids == 0).long() - # map AllenNLP @@PADDING@@ to _pad_id in specific transformer vocab - unk_mask = (ids == 1).long() - # map AllenNLP @@UNKNOWN@@ to _unk_id in specific transformer vocab - valid_mask = (ids > 1).long() - # shift ordinary indexes by 2 to match pretrained token embedding indexes - if self._unk_id is not None: - ids = (ids - 2) * valid_mask + self._pad_id * pad_mask + self._unk_id * unk_mask - else: - ids = (ids - 2) * valid_mask + self._pad_id * pad_mask - assert ( - unk_mask == 0 - ).all(), "out-of-vocabulary token found in the input, but _unk_id of transformers model is not specified" - if self.max_pos is not None: - assert ( - ids.size()[-1] <= self.max_pos - ), "input length exceeds position embedding capacity, reduce max_seq_len" - - sent[self.tokenizer_required] = ids - return ids, input_mask - - def prepare_output(self, lex_seq, hidden_states, input_mask): - """ - Convert the output of the transformers module to a vector sequence as expected by jiant. - - args: - lex_seq: The sequence of input word embeddings as a tensor (batch_size, sequence_length, hidden_size). - Used only if output_mode = "only". - hidden_states: A list of sequences of model hidden states as tensors (batch_size, sequence_length, hidden_size). - input_mask: A tensor with 1s in positions corresponding to non-padding tokens (batch_size, sequence_length). - - returns: - h: Output embedding as a tensor (batch_size, sequence_length, output_dim) - """ - available_layers = hidden_states[: self.max_layer + 1] - - if self.output_mode in ["none", "top"]: - h = available_layers[-1] - elif self.output_mode == "only": - h = lex_seq - elif self.output_mode == "cat": - h = torch.cat([available_layers[-1], lex_seq], dim=2) - elif self.output_mode == "mix": - h = self.scalar_mix(available_layers, mask=input_mask) - else: - raise NotImplementedError(f"output_mode={self.output_mode}" " not supported.") - - return h - - def get_output_dim(self): - if self.output_mode == "cat": - return 2 * self.model.config.hidden_size - else: - return self.model.config.hidden_size - - def get_seg_ids(self, token_ids, input_mask): - """ Dynamically build the segment IDs for a concatenated pair of sentences - Searches for index _sep_id in the tensor. Supports BERT or XLNet-style padding. - Sets padding tokens to segment zero. - - args: - token_ids (torch.LongTensor): batch of token IDs - input_mask (torch.LongTensor): mask of token_ids - - returns: - seg_ids (torch.LongTensor): batch of segment IDs - - example: - > sents = ["[CLS]", "I", "am", "a", "cat", ".", "[SEP]", "You", "like", "cats", "?", "[SEP]", "[PAD]"] - > token_tensor = torch.Tensor([[vocab[w] for w in sent]]) # a tensor of token indices - > seg_ids = get_seg_ids(token_tensor, torch.LongTensor([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0])) - > assert seg_ids == torch.LongTensor([0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0]) - """ - # TODO: creating sentence segment id(and language segment id for XLM) is more suitable for preprocess - sep_idxs = (token_ids == self._sep_id).long() - sep_count = torch.cumsum(sep_idxs, dim=-1) - sep_idxs - seg_ids = sep_count * input_mask - - if self._SEG_ID_CLS is not None: - seg_ids[token_ids == self._cls_id] = self._SEG_ID_CLS - - if self._SEG_ID_SEP is not None: - seg_ids[token_ids == self._sep_id] = self._SEG_ID_SEP - - return seg_ids - - @staticmethod - def apply_boundary_tokens(s1, s2=None, get_offset=False): - """ - A function that appliese the appropriate EOS/SOS/SEP/CLS tokens to token sequence or - token sequence pair for most tasks. - This function should be implmented in subclasses. - - args: - s1: list[str], tokens from sentence 1 - s2: list[str] (optional), tokens from sentence 2, used for pair embedding - get_offset: bool, returns offset if True - - returns - s: list[str], token sequence with boundry tokens - offset_s1 (optional): int, index offset of s1 - offset_s2 (optional): int, index offset of s2 - """ - raise NotImplementedError - - @staticmethod - def apply_lm_boundary_tokens(s1, get_offset=False): - """ - A function that appliese the appropriate EOS/SOS/SEP/CLS tokens to a token sequence for - language modeling tasks. - This function should be implmented in subclasses. - - args: - s1: list[str], tokens from sentence - get_offset: bool, returns offset if True - - returns - s: list[str], token sequence with boundry tokens - offset_s1 (optional): int, index offset of s1 - """ - raise NotImplementedError - - def forward(self, sent, task_name): - """ Run transformers model and return output representation - This function should be implmented in subclasses. - - args: - sent: batch dictionary, in which - sent[self.tokenizer_required]: [batch_size, var_seq_len] input token IDs - task_name: task_name string, this can used to implement different mixing scalars for - differnt tasks. See the TODO in parameter_setup for more details. - - returns: - transformer_emb: [batch_size, var_seq_len, output_dim] output embedding - """ - raise NotImplementedError - - def get_pretrained_lm_head(self): - """ Download another transformer model with LM head, extract the LM head and tie its - weight to the input token embedding. In most cases, this module needs to work with - output_mode as "top" or "none" - This function should be implmented in subclasses. - - returns: - lm_head: module [*, hidden_size] -> [*, vocab_size] - """ - raise NotImplementedError - - -class BertEmbedderModule(HuggingfaceTransformersEmbedderModule): - """ Wrapper for BERT module to fit into jiant APIs. - Check HuggingfaceTransformersEmbedderModule for function definitions """ - - def __init__(self, args): - super(BertEmbedderModule, self).__init__(args) - - self.model = transformers.BertModel.from_pretrained( - args.input_module, cache_dir=self.cache_dir, output_hidden_states=True - ) - self.max_pos = self.model.config.max_position_embeddings - - self.tokenizer = transformers.BertTokenizer.from_pretrained( - args.input_module, cache_dir=self.cache_dir, do_lower_case="uncased" in args.tokenizer - ) # TODO: Speed things up slightly by reusing the previously-loaded tokenizer. - self._sep_id = self.tokenizer.convert_tokens_to_ids("[SEP]") - self._cls_id = self.tokenizer.convert_tokens_to_ids("[CLS]") - self._pad_id = self.tokenizer.convert_tokens_to_ids("[PAD]") - self._unk_id = self.tokenizer.convert_tokens_to_ids("[UNK]") - self._mask_id = self.tokenizer.convert_tokens_to_ids("[MASK]") - - self.parameter_setup(args) - - @staticmethod - def apply_boundary_tokens(s1, s2=None, get_offset=False): - # BERT-style boundary token padding on string token sequences - if s2: - s = ["[CLS]"] + s1 + ["[SEP]"] + s2 + ["[SEP]"] - if get_offset: - return s, 1, len(s1) + 2 - else: - s = ["[CLS]"] + s1 + ["[SEP]"] - if get_offset: - return s, 1 - return s - - def forward(self, sent: Dict[str, torch.LongTensor], task_name: str = "") -> torch.FloatTensor: - ids, input_mask = self.correct_sent_indexing(sent) - hidden_states, lex_seq = [], None - if self.output_mode not in ["none", "top"]: - lex_seq = self.model.embeddings.word_embeddings(ids) - lex_seq = self.model.embeddings.LayerNorm(lex_seq) - if self.output_mode != "only": - token_types = self.get_seg_ids(ids, input_mask) - _, output_pooled_vec, hidden_states = self.model( - ids, token_type_ids=token_types, attention_mask=input_mask - ) - return self.prepare_output(lex_seq, hidden_states, input_mask) - - def get_pretrained_lm_head(self): - model_with_lm_head = transformers.BertForMaskedLM.from_pretrained( - self.input_module, cache_dir=self.cache_dir - ) - lm_head = model_with_lm_head.cls - lm_head.predictions.decoder.weight = self.model.embeddings.word_embeddings.weight - return lm_head - - -class RobertaEmbedderModule(HuggingfaceTransformersEmbedderModule): - """ Wrapper for RoBERTa module to fit into jiant APIs. - Check HuggingfaceTransformersEmbedderModule for function definitions """ - - def __init__(self, args): - super(RobertaEmbedderModule, self).__init__(args) - - self.model = transformers.RobertaModel.from_pretrained( - args.input_module, cache_dir=self.cache_dir, output_hidden_states=True - ) - self.max_pos = self.model.config.max_position_embeddings - - self.tokenizer = transformers.RobertaTokenizer.from_pretrained( - args.input_module, cache_dir=self.cache_dir - ) # TODO: Speed things up slightly by reusing the previously-loaded tokenizer. - self._sep_id = self.tokenizer.convert_tokens_to_ids("") - self._cls_id = self.tokenizer.convert_tokens_to_ids("") - self._pad_id = self.tokenizer.convert_tokens_to_ids("") - self._unk_id = self.tokenizer.convert_tokens_to_ids("") - self._mask_id = self.tokenizer.convert_tokens_to_ids("") - - self.parameter_setup(args) - - @staticmethod - def apply_boundary_tokens(s1, s2=None, get_offset=False): - # RoBERTa-style boundary token padding on string token sequences - if s2: - s = [""] + s1 + ["", ""] + s2 + [""] - if get_offset: - return s, 1, len(s1) + 3 - else: - s = [""] + s1 + [""] - if get_offset: - return s, 1 - return s - - def forward(self, sent: Dict[str, torch.LongTensor], task_name: str = "") -> torch.FloatTensor: - ids, input_mask = self.correct_sent_indexing(sent) - hidden_states, lex_seq = [], None - if self.output_mode not in ["none", "top"]: - lex_seq = self.model.embeddings.word_embeddings(ids) - lex_seq = self.model.embeddings.LayerNorm(lex_seq) - if self.output_mode != "only": - _, output_pooled_vec, hidden_states = self.model(ids, attention_mask=input_mask) - return self.prepare_output(lex_seq, hidden_states, input_mask) - - def get_pretrained_lm_head(self): - model_with_lm_head = transformers.RobertaForMaskedLM.from_pretrained( - self.input_module, cache_dir=self.cache_dir - ) - lm_head = model_with_lm_head.lm_head - lm_head.decoder.weight = self.model.embeddings.word_embeddings.weight - return lm_head - - -class AlbertEmbedderModule(HuggingfaceTransformersEmbedderModule): - """ Wrapper for ALBERT module to fit into jiant APIs. - Check HuggingfaceTransformersEmbedderModule for function definitions """ - - def __init__(self, args): - super(AlbertEmbedderModule, self).__init__(args) - - self.model = transformers.AlbertModel.from_pretrained( - args.input_module, cache_dir=self.cache_dir, output_hidden_states=True - ) - self.max_pos = self.model.config.max_position_embeddings - - self.tokenizer = transformers.AlbertTokenizer.from_pretrained( - args.input_module, cache_dir=self.cache_dir - ) # TODO: Speed things up slightly by reusing the previously-loaded tokenizer. - self._sep_id = self.tokenizer.convert_tokens_to_ids("[SEP]") - self._cls_id = self.tokenizer.convert_tokens_to_ids("[CLS]") - self._pad_id = self.tokenizer.convert_tokens_to_ids("") - self._unk_id = self.tokenizer.convert_tokens_to_ids("") - self._mask_id = self.tokenizer.convert_tokens_to_ids("[MASK]") - - self.parameter_setup(args) - - @staticmethod - def apply_boundary_tokens(s1, s2=None, get_offset=False): - # ALBERT-style boundary token padding on string token sequences - if s2: - s = ["[CLS]"] + s1 + ["[SEP]"] + s2 + ["[SEP]"] - if get_offset: - return s, 1, len(s1) + 2 - else: - s = ["[CLS]"] + s1 + ["[SEP]"] - if get_offset: - return s, 1 - return s - - def forward(self, sent: Dict[str, torch.LongTensor], task_name: str = "") -> torch.FloatTensor: - ids, input_mask = self.correct_sent_indexing(sent) - hidden_states, lex_seq = [], None - if self.output_mode not in ["none", "top"]: - lex_seq = self.model.embeddings.word_embeddings(ids) - lex_seq = self.model.embeddings.LayerNorm(lex_seq) - if self.output_mode != "only": - token_types = self.get_seg_ids(ids, input_mask) - _, output_pooled_vec, hidden_states = self.model( - ids, token_type_ids=token_types, attention_mask=input_mask - ) - return self.prepare_output(lex_seq, hidden_states, input_mask) - - def get_pretrained_lm_head(self): - model_with_lm_head = transformers.AlbertForMaskedLM.from_pretrained( - self.input_module, cache_dir=self.cache_dir - ) - lm_head = model_with_lm_head.predictions - lm_head.decoder.weight = self.model.embeddings.word_embeddings.weight - return lm_head - - -class XLNetEmbedderModule(HuggingfaceTransformersEmbedderModule): - """ Wrapper for XLNet module to fit into jiant APIs. - Check HuggingfaceTransformersEmbedderModule for function definitions """ - - def __init__(self, args): - super(XLNetEmbedderModule, self).__init__(args) - - self.model = transformers.XLNetModel.from_pretrained( - args.input_module, cache_dir=self.cache_dir, output_hidden_states=True - ) - - self.tokenizer = transformers.XLNetTokenizer.from_pretrained( - args.input_module, cache_dir=self.cache_dir, do_lower_case="uncased" in args.tokenizer - ) # TODO: Speed things up slightly by reusing the previously-loaded tokenizer. - self._sep_id = self.tokenizer.convert_tokens_to_ids("") - self._cls_id = self.tokenizer.convert_tokens_to_ids("") - self._pad_id = self.tokenizer.convert_tokens_to_ids("") - self._unk_id = self.tokenizer.convert_tokens_to_ids("") - self._mask_id = self.tokenizer.convert_tokens_to_ids("") - - self.parameter_setup(args) - - # Segment IDs for CLS and SEP tokens. Unlike in BERT, these aren't part of the usual 0/1 - # input segments. Standard constants reused from transformers. They aren't actually - # used within the transformers code, so we're reproducing them here in case they're - # removed in a later cleanup. - self._SEG_ID_CLS = 2 - self._SEG_ID_SEP = 3 - - @staticmethod - def apply_boundary_tokens(s1, s2=None, get_offset=False): - # XLNet-style boundary token marking on string token sequences - if s2: - s = s1 + [""] + s2 + ["", ""] - if get_offset: - return s, 0, len(s1) + 1 - else: - s = s1 + ["", ""] - if get_offset: - return s, 0 - return s - - def forward(self, sent: Dict[str, torch.LongTensor], task_name: str = "") -> torch.FloatTensor: - ids, input_mask = self.correct_sent_indexing(sent) - hidden_states, lex_seq = [], None - if self.output_mode not in ["none", "top"]: - lex_seq = self.model.word_embedding(ids) - if self.output_mode != "only": - token_types = self.get_seg_ids(ids, input_mask) - _, output_mems, hidden_states = self.model( - ids, token_type_ids=token_types, attention_mask=input_mask - ) - return self.prepare_output(lex_seq, hidden_states, input_mask) - - def get_pretrained_lm_head(self, args): - model_with_lm_head = transformers.XLNetLMHeadModel.from_pretrained( - self.input_module, cache_dir=self.cache_dir - ) - lm_head = model_with_lm_head.lm_loss - lm_head.weight = self.model.word_embedding.weight - return lm_head - - -class OpenAIGPTEmbedderModule(HuggingfaceTransformersEmbedderModule): - """ Wrapper for OpenAI GPT module to fit into jiant APIs. - Check HuggingfaceTransformersEmbedderModule for function definitions """ - - def __init__(self, args): - super(OpenAIGPTEmbedderModule, self).__init__(args) - - self.model = transformers.OpenAIGPTModel.from_pretrained( - args.input_module, cache_dir=self.cache_dir, output_hidden_states=True - ) # TODO: Speed things up slightly by reusing the previously-loaded tokenizer. - self.max_pos = self.model.config.n_positions - - self.tokenizer = transformers.OpenAIGPTTokenizer.from_pretrained( - args.input_module, cache_dir=self.cache_dir - ) - self._pad_id = self.tokenizer.convert_tokens_to_ids("\n") - self._unk_id = self.tokenizer.convert_tokens_to_ids("") - - special_tokens = {"bos_token": "", "sep_token": "", "cls_token": ""} - self.tokenizer.add_special_tokens(special_tokens) - self.model.resize_token_embeddings(len(self.tokenizer)) - - self.parameter_setup(args) - - @staticmethod - def apply_boundary_tokens(s1, s2=None, get_offset=False): - # OpenAI-GPT-style boundary token marking on string token sequences - if s2: - s = [""] + s1 + [""] + s2 + [""] - if get_offset: - return s, 1, len(s1) + 2 - else: - s = [""] + s1 + [""] - if get_offset: - return s, 1 - return s - - @staticmethod - def apply_lm_boundary_tokens(s1, get_offset=False): - # OpenAI-GPT-style boundary token marking on string token sequences for LM tasks - s = ["\n"] + s1 + ["\n"] - if get_offset: - return s, 1 - return s - - def forward(self, sent: Dict[str, torch.LongTensor], task_name: str = "") -> torch.FloatTensor: - ids, input_mask = self.correct_sent_indexing(sent) - hidden_states, lex_seq = [], None - if self.output_mode not in ["none", "top"]: - lex_seq = self.model.tokens_embed(ids) - if self.output_mode != "only": - _, hidden_states = self.model(ids) - return self.prepare_output(lex_seq, hidden_states, input_mask) - - def get_pretrained_lm_head(self, args): - model_with_lm_head = transformers.OpenAIGPTLMHeadModel.from_pretrained( - self.input_module, cache_dir=self.cache_dir - ) - lm_head = model_with_lm_head.lm_head - lm_head.weight = self.model.tokens_embed.weight[: lm_head.weight.size()[0]] - return lm_head - - -class GPT2EmbedderModule(HuggingfaceTransformersEmbedderModule): - """ Wrapper for GPT-2 module to fit into jiant APIs. - Check HuggingfaceTransformersEmbedderModule for function definitions """ - - def __init__(self, args): - super(GPT2EmbedderModule, self).__init__(args) - - self.model = transformers.GPT2Model.from_pretrained( - args.input_module, cache_dir=self.cache_dir, output_hidden_states=True - ) # TODO: Speed things up slightly by reusing the previously-loaded tokenizer. - self.max_pos = self.model.config.n_positions - - self.tokenizer = transformers.GPT2Tokenizer.from_pretrained( - args.input_module, cache_dir=self.cache_dir - ) - self._pad_id = self.tokenizer.convert_tokens_to_ids("<|endoftext|>") - - special_tokens = {"bos_token": "", "sep_token": "", "cls_token": ""} - self.tokenizer.add_special_tokens(special_tokens) - self.model.resize_token_embeddings(len(self.tokenizer)) - - self.parameter_setup(args) - - @staticmethod - def apply_boundary_tokens(s1, s2=None, get_offset=False): - # GPT-2-style boundary token marking on string token sequences - if s2: - s = [""] + s1 + [""] + s2 + [""] - if get_offset: - return s, 1, len(s1) + 2 - else: - s = [""] + s1 + [""] - if get_offset: - return s, 1 - return s - - @staticmethod - def apply_lm_boundary_tokens(s1, get_offset=False): - # GPT-2-style boundary token marking on string token sequences for LM tasks - s = ["<|endoftext|>"] + s1 + ["<|endoftext|>"] - if get_offset: - return s, 1 - return s - - def forward(self, sent: Dict[str, torch.LongTensor], task_name: str = "") -> torch.FloatTensor: - ids, input_mask = self.correct_sent_indexing(sent) - hidden_states, lex_seq = [], None - if self.output_mode not in ["none", "top"]: - lex_seq = self.model.wte(ids) - if self.output_mode != "only": - _, _, hidden_states = self.model(ids) - return self.prepare_output(lex_seq, hidden_states, input_mask) - - def get_pretrained_lm_head(self): - model_with_lm_head = transformers.GPT2LMHeadModel.from_pretrained( - self.input_module, cache_dir=self.cache_dir - ) - lm_head = model_with_lm_head.lm_head - lm_head.weight = self.model.wte.weight[: lm_head.weight.size()[0]] - return lm_head - - -class TransfoXLEmbedderModule(HuggingfaceTransformersEmbedderModule): - """ Wrapper for Transformer-XL module to fit into jiant APIs. - Check HuggingfaceTransformersEmbedderModule for function definitions """ - - def __init__(self, args): - super(TransfoXLEmbedderModule, self).__init__(args) - - self.model = transformers.TransfoXLModel.from_pretrained( - args.input_module, cache_dir=self.cache_dir, output_hidden_states=True - ) # TODO: Speed things up slightly by reusing the previously-loaded tokenizer. - - self.tokenizer = transformers.TransfoXLTokenizer.from_pretrained( - args.input_module, cache_dir=self.cache_dir - ) - self._pad_id = self.tokenizer.convert_tokens_to_ids("") - self._unk_id = self.tokenizer.convert_tokens_to_ids("") - - special_tokens = {"bos_token": "", "sep_token": "", "cls_token": ""} - self.tokenizer.add_special_tokens(special_tokens) - self.model.resize_token_embeddings(len(self.tokenizer)) - - self.parameter_setup(args) - - @staticmethod - def apply_boundary_tokens(s1, s2=None, get_offset=False): - # TransformerXL-style boundary token marking on string token sequences - if s2: - s = [""] + s1 + [""] + s2 + [""] - if get_offset: - return s, 1, len(s1) + 2 - else: - s = [""] + s1 + [""] - if get_offset: - return s, 1 - return s - - @staticmethod - def apply_lm_boundary_tokens(s1, get_offset=False): - # TransformerXL-style boundary token marking on string token sequences for LM tasks - s = ["<\n>"] + s1 + ["<\n>"] - if get_offset: - return s, 1 - return s - - def forward(self, sent: Dict[str, torch.LongTensor], task_name: str = "") -> torch.FloatTensor: - ids, input_mask = self.correct_sent_indexing(sent) - hidden_states, lex_seq = [], None - if self.output_mode not in ["none", "top"]: - lex_seq = self.model.word_emb(ids) - if self.output_mode != "only": - _, _, hidden_states = self.model(ids) - return self.prepare_output(lex_seq, hidden_states, input_mask) - - def get_pretrained_lm_head(self): - # Note: transformers didn't implement TransfoXLLMHeadModel, use this in eval only - model_with_lm_head = transformers.TransfoXLLMHeadModel.from_pretrained( - self.input_module, cache_dir=self.cache_dir - ) - lm_head = model_with_lm_head.crit - for i in range(len(model_with_lm_head.crit.out_layers) - 1): - lm_head.out_layers[i].weight = self.model.word_emb.emb_layers[i].weights - lm_head.out_layers[-1].weight = self.model.word_emb.emb_layers[-1].weight[ - : lm_head.out_layers[-1].weight.size()[0] - ] - for i, tie_proj in enumerate(model_with_lm_head.config.tie_projs): - if tie_proj: - lm_head.out_projs[i] = self.model.word_emb.emb_projs[i] - return lm_head - - -class XLMEmbedderModule(HuggingfaceTransformersEmbedderModule): - """ Wrapper for XLM module to fit into jiant APIs. - Check HuggingfaceTransformersEmbedderModule for function definitions """ - - def __init__(self, args): - super(XLMEmbedderModule, self).__init__(args) - - self.model = transformers.XLMModel.from_pretrained( - args.input_module, cache_dir=self.cache_dir, output_hidden_states=True - ) # TODO: Speed things up slightly by reusing the previously-loaded tokenizer. - self.max_pos = self.model.config.max_position_embeddings - - self.tokenizer = transformers.XLMTokenizer.from_pretrained( - args.input_module, cache_dir=self.cache_dir - ) - self._unk_id = self.tokenizer.convert_tokens_to_ids("") - self._pad_id = self.tokenizer.convert_tokens_to_ids("") - - self.parameter_setup(args) - - @staticmethod - def apply_boundary_tokens(s1, s2=None, get_offset=False): - # XLM-style boundary token marking on string token sequences - if s2: - s = [""] + s1 + [""] + s2 + [""] - if get_offset: - return s, 1, len(s1) + 2 - else: - s = [""] + s1 + [""] - if get_offset: - return s, 1, len(s1) + 1 - return s - - def forward(self, sent: Dict[str, torch.LongTensor], task_name: str = "") -> torch.FloatTensor: - ids, input_mask = self.correct_sent_indexing(sent) - hidden_states, lex_seq = [], None - if self.output_mode not in ["none", "top"]: - lex_seq = self.model.embeddings(ids) - if self.output_mode != "only": - _, hidden_states = self.model(ids) - return self.prepare_output(lex_seq, hidden_states, input_mask) - - def get_pretrained_lm_head(self): - model_with_lm_head = transformers.XLMWithLMHeadModel.from_pretrained( - self.input_module, cache_dir=self.cache_dir - ) - lm_head = model_with_lm_head.pred_layer - lm_head.proj.weight = self.model.embeddings.weight - return lm_head diff --git a/jiant/metrics/nli_metrics.py b/jiant/metrics/nli_metrics.py deleted file mode 100644 index 91f6b949e..000000000 --- a/jiant/metrics/nli_metrics.py +++ /dev/null @@ -1,89 +0,0 @@ -from typing import Optional - -from overrides import overrides -import torch - -from allennlp.common.checks import ConfigurationError -from allennlp.training.metrics.metric import Metric - - -@Metric.register("nli_two_class_accuracy") -class NLITwoClassAccuracy(Metric): - """ - Metric that evaluates two-way NLI classifiers on three-way data or vice-versa. - - Thhis computes standard accuracy, but collapses 'neutral' and 'contradiction' - into one label, assuming that 'entailment' is at index 1 (as in the jiant - implementations of SNLI, MNLI and RTE). - - Based on allennlp.training.metrics.CategoricalAccuracy. - """ - - def __init__(self) -> None: - self.correct_count = 0.0 - self.total_count = 0.0 - - def __call__( - self, - predictions: torch.Tensor, - gold_labels: torch.Tensor, - mask: Optional[torch.Tensor] = None, - ): - """ - Parameters - ---------- - predictions : ``torch.Tensor``, required. - A tensor of predictions of shape (batch_size, ..., num_classes). - gold_labels : ``torch.Tensor``, required. - A tensor of integer class label of shape (batch_size, ...). It must be the same - shape as the ``predictions`` tensor without the ``num_classes`` dimension. - mask: ``torch.Tensor``, optional (default = None). - A masking tensor the same size as ``gold_labels``. - """ - predictions, gold_labels, mask = self.unwrap_to_tensors(predictions, gold_labels, mask) - - # Some sanity checks. - num_classes = predictions.size(-1) - if gold_labels.dim() != predictions.dim() - 1: - raise ConfigurationError( - "gold_labels must have dimension == predictions.size() - 1 but " - "found tensor of shape: {}".format(predictions.size()) - ) - - predictions = predictions.view((-1, num_classes)) - gold_labels = gold_labels.view(-1).long() - - top_one_preds = predictions.max(-1)[1].unsqueeze(-1) - - # NLI-specific filtering - top_one_preds = top_one_preds == 1 - gold_labels = gold_labels == 1 - - # This is of shape (batch_size, ..., top_one_preds). - correct = top_one_preds.eq(gold_labels.unsqueeze(-1)).float() - - if mask is not None: - correct *= mask.view(-1, 1).float() - self.total_count += mask.sum() - else: - self.total_count += gold_labels.numel() - self.correct_count += correct.sum() - - def get_metric(self, reset: bool = False): - """ - Returns - ------- - The accumulated accuracy. - """ - if self.total_count > 1e-12: - accuracy = float(self.correct_count) / float(self.total_count) - else: - accuracy = 0.0 - if reset: - self.reset() - return accuracy - - @overrides - def reset(self): - self.correct_count = 0.0 - self.total_count = 0.0 diff --git a/jiant/metrics/span_metrics.py b/jiant/metrics/span_metrics.py deleted file mode 100644 index 8d52689b7..000000000 --- a/jiant/metrics/span_metrics.py +++ /dev/null @@ -1,97 +0,0 @@ -import collections -import string -import re - -from typing import List, Dict - -from allennlp.training.metrics.metric import Metric - - -def normalize_answer(s): - """Lower text and remove punctuation, articles and extra whitespace. - From official ReCoRD eval script """ - - def remove_articles(text): - return re.sub(r"\b(a|an|the)\b", " ", text) - - def white_space_fix(text): - return " ".join(text.split()) - - def remove_punc(text): - exclude = set(string.punctuation) - return "".join(ch for ch in text if ch not in exclude) - - def lower(text): - return text.lower() - - return white_space_fix(remove_articles(remove_punc(lower(s)))) - - -def f1_score(prediction, ground_truth): - """ Compute normalized token level F1 - From official ReCoRD eval script """ - prediction_tokens = normalize_answer(prediction).split() - ground_truth_tokens = normalize_answer(ground_truth).split() - common = collections.Counter(prediction_tokens) & collections.Counter(ground_truth_tokens) - num_same = sum(common.values()) - if num_same == 0: - return 0 - precision = 1.0 * num_same / len(prediction_tokens) - recall = 1.0 * num_same / len(ground_truth_tokens) - f1 = (2 * precision * recall) / (precision + recall) - return f1 - - -def exact_match_score(prediction, ground_truth): - """ Compute normalized exact match - From official ReCoRD eval script """ - return normalize_answer(prediction) == normalize_answer(ground_truth) - - -def metric_max_over_ground_truths(metric_fn, prediction, ground_truths): - """ Compute max metric between prediction and each ground truth. - From official ReCoRD eval script """ - scores_for_ground_truths = [] - for ground_truth in ground_truths: - score = metric_fn(prediction, ground_truth) - scores_for_ground_truths.append(score) - return max(scores_for_ground_truths) - - -class GenericSpanMetric(Metric): - def __init__(self): - self._metric_total = 0 - self._count = 0 - - def metric_func(self, prediction, ground_truth): - raise NotImplementedError - - def __call__(self, pred_str_list: List[str], gold_str_list: List[str]): - # Breaking API here. Should we make Metric more general? - metric_ls = [ - self.metric_func(prediction=pred_str, ground_truth=gold_str) - for pred_str, gold_str in zip(pred_str_list, gold_str_list) - ] - - self._metric_total += sum(metric_ls) - self._count += len(metric_ls) - - def get_metric(self, reset: bool = False): - metric = self._metric_total / self._count - if reset: - self.reset() - return metric - - def reset(self): - self._metric_total = 0 - self._count = 0 - - -class F1SpanMetric(GenericSpanMetric): - def metric_func(self, prediction, ground_truth): - return f1_score(prediction=prediction, ground_truth=ground_truth) - - -class ExactMatchSpanMetric(GenericSpanMetric): - def metric_func(self, prediction, ground_truth): - return exact_match_score(prediction=prediction, ground_truth=ground_truth) diff --git a/jiant/metrics/winogender_metrics.py b/jiant/metrics/winogender_metrics.py deleted file mode 100644 index b3ad60379..000000000 --- a/jiant/metrics/winogender_metrics.py +++ /dev/null @@ -1,43 +0,0 @@ -class GenderParity: - """ - Gender parity metric from https://github.com/decompositional-semantics-initiative/DNC. - """ - - def __init__(self): - self.same_preds = 0.0 - self.diff_preds = 0.0 - - def get_metric(self, reset=False): - if self.same_preds + self.diff_preds == 0: - return -1 - gender_parity = float(self.same_preds) / float(self.same_preds + self.diff_preds) - if reset: - self.same_preds = 0.0 - self.diff_preds = 0.0 - return gender_parity - - def __call__(self, predictions): - """ - Calculate gender parity. - Parameters - ------------------- - predictions: list of dicts with fields - sent2_str: str, hypothesis sentence, - sent1_str: str, context sentence, - preds: int, - pair_id: int - - Returns - ------------------- - None - """ - for idx in range(int(len(predictions) / 2)): - pred1 = predictions[idx * 2] - pred2 = predictions[(idx * 2) + 1] - assert ( - pred1["sent2_str"] == pred2["sent2_str"] - ), "Mismatched hypotheses for ids %s and %s" % (str(pred1["idx"]), str(pred2["idx"])) - if pred1["preds"] == pred2["preds"]: - self.same_preds += 1 - else: - self.diff_preds += 1 diff --git a/jiant/models.py b/jiant/models.py deleted file mode 100644 index 491a647ac..000000000 --- a/jiant/models.py +++ /dev/null @@ -1,1398 +0,0 @@ -"""Core model and functions for building it.""" -import copy -import json -import logging as log -import os -from typing import Dict, List - -import numpy as np -import torch -import torch.nn as nn -import torch.nn.functional as F - -from allennlp.common import Params -from allennlp.modules.seq2seq_encoders import Seq2SeqEncoder as s2s_e -from allennlp.modules.seq2seq_encoders import StackedSelfAttentionEncoder -from allennlp.modules.seq2vec_encoders import CnnEncoder -from allennlp.modules.token_embedders import Embedding, TokenCharactersEncoder -from allennlp.training.metrics import Average -from sklearn.metrics import mean_squared_error - -from jiant.allennlp_mods.elmo_text_field_embedder import ( - ElmoTextFieldEmbedder, - ElmoTokenEmbedderWrapper, -) - -from jiant.modules.edge_probing import EdgeClassifierModule -from jiant.modules.simple_modules import ( - Pooler, - Classifier, - SingleClassifier, - PairClassifier, - NullPhraseLayer, - TokenMultiProjectionEncoder, - SOPClassifier, -) -from jiant.modules.attn_pair_encoder import AttnPairEncoder -from jiant.modules.sentence_encoder import SentenceEncoder -from jiant.modules.bilm_encoder import BiLMEncoder -from jiant.modules.bow_sentence_encoder import BoWSentEncoder -from jiant.modules.elmo_character_encoder import ElmoCharacterEncoder -from jiant.modules.onlstm_phrase_layer import ONLSTMPhraseLayer -from jiant.modules.prpn_phrase_layer import PRPNPhraseLayer -from jiant.modules.onlstm.ON_LSTM import ONLSTMStack -from jiant.modules.prpn.PRPN import PRPN -from jiant.modules.seq2seq_decoder import Seq2SeqDecoder -from jiant.modules.span_modules import SpanClassifierModule -from jiant.huggingface_transformers_interface import input_module_uses_transformers -from jiant.tasks.edge_probing import EdgeProbingTask -from jiant.tasks.lm import AutoregressiveLanguageModelingTask, MaskedLanguageModelingTask -from jiant.tasks.lm_parsing import LanguageModelingParsingTask -from jiant.tasks.qa import MultiRCTask, ReCoRDTask -from jiant.tasks.seq2seq import Seq2SeqTask -from jiant.tasks.tasks import ( - GLUEDiagnosticTask, - MultipleChoiceTask, - PairClassificationTask, - PairOrdinalRegressionTask, - PairRegressionTask, - RegressionTask, - SequenceGenerationTask, - SingleClassificationTask, - SpanClassificationTask, - SpanPredictionTask, - STSBTask, - TaggingTask, - WiCTask, - MRPCTask, - QQPTask, - SentenceOrderTask, -) -from jiant.utils import config -from jiant.utils.utils import ( - assert_for_log, - get_batch_size, - get_batch_utilization, - get_elmo_mixing_weights, - maybe_make_dir, - format_output, - uses_cuda, -) -from jiant.utils.data_loaders import get_tokenizer - -# Elmo stuff -# Look in $ELMO_SRC_DIR (e.g. /usr/share/jsalt/elmo) or download from web -ELMO_OPT_NAME = "elmo_2x4096_512_2048cnn_2xhighway_options.json" -ELMO_WEIGHTS_NAME = "elmo_2x4096_512_2048cnn_2xhighway_weights.hdf5" -ELMO_SRC_DIR = ( - os.getenv("ELMO_SRC_DIR") - or "https://s3-us-west-2.amazonaws.com/allennlp/models/elmo/2x4096_512_2048cnn_2xhighway/" -) -ELMO_OPT_PATH = os.path.join(ELMO_SRC_DIR, ELMO_OPT_NAME) -ELMO_WEIGHTS_PATH = os.path.join(ELMO_SRC_DIR, ELMO_WEIGHTS_NAME) - - -def build_sent_encoder(args, vocab, d_emb, tasks, embedder, cove_layer): - # Build single sentence encoder: the main component of interest - # Need special handling for language modeling - # Note: sent_enc is expected to apply dropout to its input _and_ output if - # needed. - rnn_params = Params( - { - "input_size": d_emb, - "bidirectional": True, - "hidden_size": args.d_hid, - "num_layers": args.n_layers_enc, - } - ) - if args.sent_enc == "onlstm": - onlayer = ONLSTMPhraseLayer( - vocab, - args.d_word, - args.d_hid, - args.n_layers_enc, - args.onlstm_chunk_size, - args.onlstm_dropconnect, - args.onlstm_dropouti, - args.dropout, - args.onlstm_dropouth, - embedder, - args.batch_size, - ) - # The 'onlayer' acts as a phrase layer module for the larger SentenceEncoder module. - sent_encoder = SentenceEncoder( - vocab, - embedder, - args.n_layers_highway, - onlayer.onlayer, - skip_embs=args.skip_embs, - dropout=args.dropout, - sep_embs_for_skip=args.sep_embs_for_skip, - cove_layer=cove_layer, - ) - d_sent = args.d_word - log.info("Using ON-LSTM sentence encoder!") - elif args.sent_enc == "prpn": - prpnlayer = PRPNPhraseLayer( - vocab, - args.d_word, - args.d_hid, - args.n_layers_enc, - args.n_slots, - args.n_lookback, - args.resolution, - args.dropout, - args.idropout, - args.rdropout, - args.res, - embedder, - args.batch_size, - ) - # The 'prpn' acts as a phrase layer module for the larger SentenceEncoder module. - sent_encoder = SentenceEncoder( - vocab, - embedder, - args.n_layers_highway, - prpnlayer.prpnlayer, - skip_embs=args.skip_embs, - dropout=args.dropout, - sep_embs_for_skip=args.sep_embs_for_skip, - cove_layer=cove_layer, - ) - d_sent = args.d_word - log.info("Using PRPN sentence encoder!") - elif ( - any(isinstance(task, AutoregressiveLanguageModelingTask) for task in tasks) - or args.sent_enc == "bilm" - ): - assert_for_log(args.sent_enc in ["rnn", "bilm"], "Only RNNLM supported!") - if any(isinstance(task, AutoregressiveLanguageModelingTask) for task in tasks): - assert_for_log( - not ( - args.input_module == "elmo" - or args.input_module.startswith("bert") - or args.input_module.startswith("xlnet") - ), - f"Using input_module = {args.input_module} for language modeling is probably not a " - "good idea, since it allows the language model to use information from the right-hand " - "context.", - ) - bilm = BiLMEncoder(d_emb, args.d_hid, args.d_hid, args.n_layers_enc) - sent_encoder = SentenceEncoder( - vocab, - embedder, - args.n_layers_highway, - bilm, - skip_embs=args.skip_embs, - dropout=args.dropout, - sep_embs_for_skip=args.sep_embs_for_skip, - cove_layer=cove_layer, - ) - d_sent = 2 * args.d_hid - elif args.sent_enc == "bow": - sent_encoder = BoWSentEncoder(vocab, embedder) - assert_for_log( - not args.skip_embs, "Skip connection not currently supported with `bow` encoder." - ) - d_sent = d_emb - elif args.sent_enc == "rnn": - sent_rnn = s2s_e.by_name("lstm").from_params(copy.deepcopy(rnn_params)) - sent_encoder = SentenceEncoder( - vocab, - embedder, - args.n_layers_highway, - sent_rnn, - skip_embs=args.skip_embs, - dropout=args.dropout, - sep_embs_for_skip=args.sep_embs_for_skip, - cove_layer=cove_layer, - ) - d_sent = 2 * args.d_hid - elif args.sent_enc == "none": - # Expose word representation layer (GloVe, ELMo, etc.) directly. - assert_for_log( - args.skip_embs, - "skip_embs is false and sent_enc is none, " - "which means that your token representations are zero-dimensional. " - "Consider setting skip_embs.", - ) - phrase_layer = NullPhraseLayer(rnn_params["input_size"]) - sent_encoder = SentenceEncoder( - vocab, - embedder, - args.n_layers_highway, - phrase_layer, - skip_embs=args.skip_embs, - dropout=args.dropout, - sep_embs_for_skip=args.sep_embs_for_skip, - cove_layer=cove_layer, - ) - d_sent = 0 - else: - assert_for_log( - False, f"Shared encoder layer specification `{args.sent_enc}` not recognized." - ) - return sent_encoder, d_sent - - -def build_model(args, vocab, pretrained_embs, tasks, cuda_devices): - """ - Build model according to args - Returns: model which has attributes set in it with the attrbutes. - """ - - # Build embeddings. - cove_layer = None - if args.input_module.startswith("bert-"): - from jiant.huggingface_transformers_interface.modules import BertEmbedderModule - - log.info(f"Using BERT model ({args.input_module}).") - embedder = BertEmbedderModule(args) - d_emb = embedder.get_output_dim() - elif args.input_module.startswith("roberta-") or args.input_module.startswith( - "nyu-mll/roberta-" - ): - from jiant.huggingface_transformers_interface.modules import RobertaEmbedderModule - - log.info(f"Using RoBERTa model ({args.input_module}).") - embedder = RobertaEmbedderModule(args) - d_emb = embedder.get_output_dim() - elif args.input_module.startswith("albert-"): - from jiant.huggingface_transformers_interface.modules import AlbertEmbedderModule - - log.info(f"Using ALBERT model ({args.input_module}).") - embedder = AlbertEmbedderModule(args) - d_emb = embedder.get_output_dim() - elif args.input_module.startswith("xlnet-"): - from jiant.huggingface_transformers_interface.modules import XLNetEmbedderModule - - log.info(f"Using XLNet model ({args.input_module}).") - embedder = XLNetEmbedderModule(args) - d_emb = embedder.get_output_dim() - elif args.input_module.startswith("openai-gpt"): - from jiant.huggingface_transformers_interface.modules import OpenAIGPTEmbedderModule - - log.info(f"Using OpenAI GPT model ({args.input_module}).") - embedder = OpenAIGPTEmbedderModule(args) - d_emb = embedder.get_output_dim() - elif args.input_module.startswith("gpt2"): - from jiant.huggingface_transformers_interface.modules import GPT2EmbedderModule - - log.info(f"Using GPT-2 model ({args.input_module}).") - embedder = GPT2EmbedderModule(args) - d_emb = embedder.get_output_dim() - elif args.input_module.startswith("transfo-xl-"): - from jiant.huggingface_transformers_interface.modules import TransfoXLEmbedderModule - - log.info(f"Using Transformer-XL model ({args.input_module}).") - embedder = TransfoXLEmbedderModule(args) - d_emb = embedder.get_output_dim() - elif args.input_module.startswith("xlm-"): - from jiant.huggingface_transformers_interface.modules import XLMEmbedderModule - - log.info(f"Using XLM model ({args.input_module}).") - embedder = XLMEmbedderModule(args) - d_emb = embedder.get_output_dim() - else: - # Default case, used for ELMo, CoVe, word embeddings, etc. - d_emb, embedder, cove_layer = build_embeddings(args, vocab, tasks, pretrained_embs) - - sent_encoder, d_sent_output = build_sent_encoder( - args, vocab, d_emb, tasks, embedder, cove_layer - ) - # d_task_input is the input dimension of the task-specific module - # set skip_emb = 1 if you want to concatenate the encoder input with encoder output to pass - # into task specific module. - d_task_input = d_sent_output + (args.skip_embs * d_emb) - - # Build model and classifiers - model = MultiTaskModel(args, sent_encoder, vocab, cuda_devices) - build_task_modules(args, tasks, model, d_task_input, d_emb, embedder, vocab) - model = model.cuda() if uses_cuda(cuda_devices) else model - if isinstance(cuda_devices, list): - model = nn.DataParallel(model, device_ids=cuda_devices) - - log.info("Model specification:") - log.info(model) - param_count = 0 - trainable_param_count = 0 - if args.list_params: - log.info("Model parameters:") - for name, param in model.named_parameters(): - param_count += np.prod(param.size()) - if param.requires_grad: - trainable_param_count += np.prod(param.size()) - if args.list_params: - log.info( - "\t%s: Trainable parameter, count %d with %s", - name, - np.prod(param.size()), - str(param.size()), - ) - elif args.list_params: - log.info( - "\t%s: Non-trainable parameter, count %d with %s", - name, - np.prod(param.size()), - str(param.size()), - ) - log.info("Total number of parameters: {ct:d} ({ct:g})".format(ct=param_count)) - log.info("Number of trainable parameters: {ct:d} ({ct:g})".format(ct=trainable_param_count)) - return model - - -def build_embeddings(args, vocab, tasks, pretrained_embs=None): - """ Build embeddings according to options in args """ - d_emb, d_char = 0, args.d_char - - token_embedders = {} - # Word embeddings - n_token_vocab = vocab.get_vocab_size("tokens") - if args.input_module in ["glove", "fastText"] and pretrained_embs is not None: - word_embs = pretrained_embs - assert word_embs.size()[0] == n_token_vocab - d_word = word_embs.size()[1] - log.info("\tUsing pre-trained word embeddings: %s", str(word_embs.size())) - elif args.input_module == "scratch": - log.info("\tTraining word embeddings from scratch.") - d_word = args.d_word - word_embs = nn.Embedding(n_token_vocab, d_word).weight - else: - assert input_module_uses_transformers(args.input_module) or args.input_module in [ - "elmo", - "elmo-chars-only", - ], f"'{args.input_module}' is not a valid value for input_module." - embeddings = None - word_embs = None - - if word_embs is not None: - embeddings = Embedding( - num_embeddings=n_token_vocab, - embedding_dim=d_word, - weight=word_embs, - trainable=(args.embeddings_train == 1), - padding_index=vocab.get_token_index("@@PADDING@@"), - ) - token_embedders["words"] = embeddings - d_emb += d_word - - # Handle cove - cove_layer = None - if args.cove: - assert embeddings is not None - assert args.input_module == "glove", "CoVe requires GloVe embeddings." - assert d_word == 300, "CoVe expects 300-dimensional GloVe embeddings." - try: - from jiant.modules.cove.cove import MTLSTM as cove_lstm - - # Have CoVe do an internal GloVe lookup, but don't add residual. - # We'll do this manually in modules.py; see - # SentenceEncoder.forward(). - cove_layer = cove_lstm(n_vocab=n_token_vocab, vectors=embeddings.weight.data) - # Control whether CoVe is trainable. - for param in cove_layer.parameters(): - param.requires_grad = bool(args.cove_fine_tune) - d_emb += 600 # 300 x 2 for biLSTM activations - log.info("\tUsing CoVe embeddings!") - except ImportError as e: - log.info("Failed to import CoVe!") - raise e - - # Character embeddings - if args.char_embs: - log.info("\tUsing character embeddings!") - char_embeddings = Embedding(vocab.get_vocab_size("chars"), d_char) - filter_sizes = tuple([int(i) for i in args.char_filter_sizes.split(",")]) - char_encoder = CnnEncoder( - d_char, - num_filters=args.n_char_filters, - ngram_filter_sizes=filter_sizes, - output_dim=d_char, - ) - char_embedder = TokenCharactersEncoder( - char_embeddings, char_encoder, dropout=args.dropout_embs - ) - d_emb += d_char - token_embedders["chars"] = char_embedder - else: - log.info("\tNot using character embeddings!") - - # If we want separate ELMo scalar weights (a different ELMo representation for each classifier, - # then we need count and reliably map each classifier to an index used by - # allennlp internal ELMo. - if args.sep_embs_for_skip: - # Determine a deterministic list of classifier names to use for each - # task. - classifiers = sorted(set(map(lambda x: x._classifier_name, tasks))) - # Reload existing classifier map, if it exists. - classifier_save_path = args.run_dir + "/classifier_task_map.json" - if os.path.isfile(classifier_save_path): - loaded_classifiers = json.load(open(args.run_dir + "/classifier_task_map.json", "r")) - else: - # No file exists, so assuming we are just starting to pretrain. If pretrain is to be - # skipped, then there's a way to bypass this assertion by explicitly allowing for - # a missing classiifer task map. - assert_for_log( - args.do_pretrain or args.allow_missing_task_map, - "Error: {} should already exist.".format(classifier_save_path), - ) - if args.allow_missing_task_map: - log.warning( - "Warning: classifier task map not found in model" - " directory. Creating a new one from scratch." - ) - # default is always @pretrain@ - loaded_classifiers = {"@pretrain@": 0} - # Add the new tasks and update map, keeping the internal ELMo index - # consistent. - max_number_classifiers = max(loaded_classifiers.values()) - offset = 1 - for classifier in classifiers: - if classifier not in loaded_classifiers: - loaded_classifiers[classifier] = max_number_classifiers + offset - offset += 1 - log.info("Classifiers:{}".format(loaded_classifiers)) - open(classifier_save_path, "w+").write(json.dumps(loaded_classifiers)) - # Every index in classifiers needs to correspond to a valid ELMo output - # representation. - num_reps = 1 + max(loaded_classifiers.values()) - else: - # All tasks share the same scalars. - # Not used if input_module = elmo-chars-only (i.e. no elmo) - loaded_classifiers = {"@pretrain@": 0} - num_reps = 1 - if args.input_module.startswith("elmo"): - log.info("Loading ELMo from files:") - log.info("ELMO_OPT_PATH = %s", ELMO_OPT_PATH) - if args.input_module == "elmo-chars-only": - log.info("\tUsing ELMo character CNN only!") - log.info("ELMO_WEIGHTS_PATH = %s", ELMO_WEIGHTS_PATH) - elmo_embedder = ElmoCharacterEncoder( - options_file=ELMO_OPT_PATH, weight_file=ELMO_WEIGHTS_PATH, requires_grad=False - ) - d_emb += 512 - else: - log.info("\tUsing full ELMo! (separate scalars/task)") - if args.elmo_weight_file_path != "none": - assert os.path.exists(args.elmo_weight_file_path), ( - 'ELMo weight file path "' + args.elmo_weight_file_path + '" does not exist.' - ) - weight_file = args.elmo_weight_file_path - else: - weight_file = ELMO_WEIGHTS_PATH - log.info("ELMO_WEIGHTS_PATH = %s", weight_file) - elmo_embedder = ElmoTokenEmbedderWrapper( - options_file=ELMO_OPT_PATH, - weight_file=weight_file, - num_output_representations=num_reps, - # Dropout is added by the sentence encoder later. - dropout=0.0, - ) - d_emb += 1024 - - token_embedders["elmo"] = elmo_embedder - - # Wrap ELMo and other embedders, and concatenates the resulting - # representations alone the last (vector) dimension. - embedder = ElmoTextFieldEmbedder( - token_embedders, - loaded_classifiers, - elmo_chars_only=args.input_module == "elmo-chars-only", - sep_embs_for_skip=args.sep_embs_for_skip, - ) - - assert d_emb, "You turned off all the embeddings, ya goof!" - return d_emb, embedder, cove_layer - - -def build_task_modules(args, tasks, model, d_sent, d_emb, embedder, vocab): - """ - This function gets the task-specific parameters and builds - the task-specific modules. - """ - - # Attach task-specific params. - for task in sorted(set(tasks), key=lambda x: x.name): - task_params = get_task_specific_params(args, task.name) - log.info( - "\tTask '%s' params: %s", - task.name, - json.dumps(task_params.as_dict(quiet=True), indent=2), - ) - # Store task-specific params in case we want to access later - setattr(model, "%s_task_params" % task.name, task_params) - - # Actually construct modules. - for task in sorted(set(tasks), key=lambda x: x.name): - # If the name of the task is different than the classifier it should use - # then skip the module creation. - if task.name != model._get_task_params(task.name).get("use_classifier", task.name): - log.info("Name of the task is different than the classifier it should use") - continue - build_task_specific_modules(task, model, d_sent, d_emb, vocab, embedder, args) - - -def build_task_specific_modules(task, model, d_sent, d_emb, vocab, embedder, args): - """ Build task-specific components for a task and add them to model. - These include decoders, linear layers for linear models. - """ - task_params = model._get_task_params(task.name) - if isinstance(task, SingleClassificationTask): - module = build_single_sentence_module( - task=task, - d_inp=d_sent, - project_before_pooling=model.project_before_pooling, - params=task_params, - ) - setattr(model, "%s_mdl" % task.name, module) - elif isinstance(task, (PairClassificationTask, PairRegressionTask, PairOrdinalRegressionTask)): - module = build_pair_sentence_module(task, d_sent, model=model, params=task_params) - setattr(model, "%s_mdl" % task.name, module) - elif isinstance(task, SpanPredictionTask): - module = TokenMultiProjectionEncoder( - projection_names=["span_start", "span_end"], d_inp=d_sent - ) - setattr(model, "%s_mdl" % task.name, module) - elif isinstance(task, LanguageModelingParsingTask): - # The LM Parsing task does not support embeddings that use skip_embs. - hid2voc = build_lm(task, d_sent, args) - setattr(model, "%s_hid2voc" % task.name, hid2voc) - setattr(model, "%s_mdl" % task.name, hid2voc) - elif isinstance(task, MaskedLanguageModelingTask): - module = build_mlm(model.sent_encoder._text_field_embedder) - setattr(model, "%s_mdl" % task.name, module) - elif isinstance(task, AutoregressiveLanguageModelingTask): - assert not input_module_uses_transformers(args.input_module), ( - "our LM Task does not support transformers, if you need them, try to update", - "corresponding parts of the code. You may find get_pretrained_lm_head and", - "apply_lm_boundary_tokens from huggingface_transformers_interface.module useful,", - "do check if they are working correctly though.", - ) - d_sent = args.d_hid + (args.skip_embs * d_emb) - hid2voc = build_lm(task, d_sent, args) - setattr(model, "%s_hid2voc" % task.name, hid2voc) - elif isinstance(task, SpanClassificationTask): - module = build_span_classifier(task, d_sent, task_params) - setattr(model, "%s_mdl" % task.name, module) - elif isinstance(task, TaggingTask): - hid2tag = build_tagger(task, d_sent, task.num_tags) - setattr(model, "%s_mdl" % task.name, hid2tag) - elif isinstance(task, MultipleChoiceTask): - module = build_multiple_choice_module( - task, d_sent, project_before_pooling=model.project_before_pooling, params=task_params - ) - setattr(model, "%s_mdl" % task.name, module) - elif isinstance(task, EdgeProbingTask): - module = EdgeClassifierModule(task, d_sent, task_params) - setattr(model, "%s_mdl" % task.name, module) - elif isinstance(task, Seq2SeqTask): - log.info("using {} attention".format(args.s2s["attention"])) - decoder_params = Params( - { - "input_dim": d_sent, - "target_embedding_dim": 300, - "decoder_hidden_size": args.s2s["d_hid_dec"], - "output_proj_input_dim": args.s2s["output_proj_input_dim"], - "max_decoding_steps": args.max_seq_len, - "target_namespace": task._label_namespace - if hasattr(task, "_label_namespace") - else "targets", - "attention": args.s2s["attention"], - "dropout": args.dropout, - "scheduled_sampling_ratio": 0.0, - "beam_size": args.s2s["beam_size"], - } - ) - decoder = Seq2SeqDecoder(vocab, **decoder_params) - setattr(model, "%s_decoder" % task.name, decoder) - elif isinstance(task, SequenceGenerationTask): - decoder, hid2voc = build_decoder(task, d_sent, vocab, embedder, args) - setattr(model, "%s_decoder" % task.name, decoder) - setattr(model, "%s_hid2voc" % task.name, hid2voc) - elif isinstance(task, (MultiRCTask, ReCoRDTask)): - module = build_qa_module(task, d_sent, model.project_before_pooling, task_params) - setattr(model, "%s_mdl" % task.name, module) - else: - raise ValueError("Module not found for %s" % task.name) - - -def get_task_specific_params(args, task_name): - """ Search args for parameters specific to task. - Args: - args: main-program args, a config.Params object - task_name: (string) - Returns: - AllenNLP Params object of task-specific params. - """ - - def _get_task_attr(attr_name, default=None): - return config.get_task_attr(args, task_name, attr_name, default) - - # This is confusing because a lot of parameters get renamed. - # TODO to replace with hierarchical configs and remove all the renaming and - # boilerplate. - params = {} - params["cls_type"] = _get_task_attr("classifier") - params["d_hid"] = _get_task_attr("classifier_hid_dim") - params["pool_type"] = _get_task_attr("pool_type") - params["d_proj"] = _get_task_attr("d_proj") - params["shared_pair_attn"] = args.shared_pair_attn - if args.shared_pair_attn: - params["attn"] = args.pair_attn - params["d_hid_attn"] = args.d_hid_attn - params["dropout"] = args.classifier_dropout - else: - params["attn"] = _get_task_attr("pair_attn") - params["d_hid_attn"] = _get_task_attr("d_hid_attn") - params["dropout"] = _get_task_attr("classifier_dropout") - - # Used for span/edge classification. Other tasks can safely ignore. - params["cls_loss_fn"] = _get_task_attr("span_classifier_loss_fn") - params["cls_span_pooling"] = _get_task_attr("classifier_span_pooling") - params["edgeprobe_cnn_context"] = _get_task_attr("edgeprobe_cnn_context") - params["edgeprobe_symmetric"] = _get_task_attr("edgeprobe_symmetric") - - # For NLI probing tasks, might want to use a classifier trained on - # something else (typically 'mnli'). - cls_task_name = _get_task_attr("use_classifier") - # default to this task - params["use_classifier"] = cls_task_name or task_name - - return Params(params) - - -def build_image_sent_module(task, d_inp, params): - pooler = Pooler(project=True, d_inp=d_inp, d_proj=params["d_proj"]) - return pooler - - -def build_single_sentence_module(task, d_inp: int, project_before_pooling: bool, params: Params): - """ Build a single sentence classifier - - args: - - task (Task): task object, used to get the number of output classes - - d_inp (int): input dimension to the module, needed for optional linear projection - - project_before_pooling (bool): apply a projection layer before pooling. - - params (Params): Params object with task-specific parameters - - returns: - - SingleClassifier (nn.Module): single-sentence classifier consisting of - (optional) a linear projection, pooling, and an MLP classifier - """ - pooler = Pooler( - project=project_before_pooling, - d_inp=d_inp, - d_proj=params["d_proj"], - pool_type=params["pool_type"], - ) - d_out = params["d_proj"] if project_before_pooling else d_inp - classifier = Classifier.from_params(d_out, task.n_classes, params) - module = SingleClassifier(pooler, classifier) - return module - - -def build_sop(task, d_inp, model, params): - """ - Build and load the pretrained head for the sentence order prediction task. - Right now, there is only support for ALBERT. - Parameters - ---------- - task: Task, - d_inp: int, - model: MultiTaskModel, - params: Params - - Returns - ------- - module: SOPCLassifier, which is loaded with pretrained weights from ALBERT SOP - pretraining. - - """ - input_module = model.sent_encoder._text_field_embedder.input_module - assert ( - "albert" in input_module - ), "SOP is only supported for ALBERT, please set input_module to an ALBERT model" - module = SOPClassifier(d_inp, task.n_classes, params) - # The huggingface implementation exposes the pretrained projection layer for the SOP task, which - # we use. See: https://github.com/huggingface/transformers/issues/2671 for more details. - module.pooler.project = model.sent_encoder._text_field_embedder.model.pooler - return module - - -def build_pair_sentence_module(task, d_inp, model, params): - """ Build a pair classifier, shared if necessary """ - - def build_pair_attn(d_in, d_hid_attn): - """ Build the pair model """ - d_inp_model = 2 * d_in - modeling_layer = s2s_e.by_name("lstm").from_params( - Params( - { - "input_size": d_inp_model, - "hidden_size": d_hid_attn, - "num_layers": 1, - "bidirectional": True, - } - ) - ) - pair_attn = AttnPairEncoder(model.vocab, modeling_layer, dropout=params["dropout"]) - return pair_attn - - # Build the "pooler", which does pools a variable length sequence - # possibly with a projection layer beforehand - if params["attn"] and model.project_before_pooling: - pooler = Pooler(project=False, d_inp=params["d_hid_attn"], d_proj=params["d_hid_attn"]) - d_out = params["d_hid_attn"] * 2 - else: - pooler = Pooler( - project=model.project_before_pooling, - d_inp=d_inp, - d_proj=params["d_proj"], - pool_type=params["pool_type"], - ) - d_out = params["d_proj"] if model.project_before_pooling else d_inp - - # Build an attention module if necessary - if params["shared_pair_attn"] and params["attn"]: # shared attn - if not hasattr(model, "pair_attn"): - pair_attn = build_pair_attn(d_inp, params["d_hid_attn"]) - model.pair_attn = pair_attn - else: - pair_attn = model.pair_attn - elif params["attn"]: # non-shared attn - pair_attn = build_pair_attn(d_inp, params["d_hid_attn"]) - else: # no attn - pair_attn = None - - # Build the classifier - n_classes = task.n_classes if hasattr(task, "n_classes") else 1 - if model.uses_pair_embedding: - # BERT/XLNet handle pair tasks by concatenating the inputs and classifying the joined - # sequence, so we use a single sentence classifier - if isinstance(task, WiCTask): - d_out *= 3 # also pass the two contextual word representations - classifier = Classifier.from_params(d_out, n_classes, params) - module = SingleClassifier(pooler, classifier) - else: - d_out = d_out + d_inp if isinstance(task, WiCTask) else d_out - classifier = Classifier.from_params(4 * d_out, n_classes, params) - module = PairClassifier(pooler, classifier, pair_attn) - if isinstance(task, SentenceOrderTask): - module = build_sop(task, d_inp, model, params) - return module - - -def build_lm(task, d_inp, args): - """ Build LM components (just map hidden states to vocab logits) """ - hid2voc = nn.Linear(d_inp, args.max_word_v_size) - return hid2voc - - -def build_mlm(embedder): - " Build MLM components " - lm_head = embedder.get_pretrained_lm_head() - return lm_head - - -def build_span_classifier(task, d_sent, task_params): - module = SpanClassifierModule(task, d_sent, task_params, num_spans=task.num_spans) - return module - - -def build_tagger(task, d_inp, out_dim): - """ Build tagger components. """ - hid2tag = nn.Linear(d_inp, out_dim) - return hid2tag - - -def build_multiple_choice_module(task, d_sent, project_before_pooling, params): - """ Basic parts for MC task: reduce a vector representation for each model into a scalar. """ - pooler = Pooler( - project=project_before_pooling, - d_inp=d_sent, - d_proj=params["d_proj"], - pool_type=params["pool_type"], - ) - d_out = params["d_proj"] if project_before_pooling else d_sent - choice2scalar = Classifier(d_out, n_classes=1, cls_type=params["cls_type"]) - return SingleClassifier(pooler, choice2scalar) - - -def build_decoder(task, d_inp, vocab, embedder, args): - """ Build a task specific decoder """ - rnn = s2s_e.by_name("lstm").from_params( - Params( - { - "input_size": embedder.get_output_dim(), - "hidden_size": args.s2s["d_hid_dec"], - "num_layers": args.s2s["n_layers_dec"], - "bidirectional": False, - } - ) - ) - decoder = SentenceEncoder(vocab, embedder, 0, rnn) - hid2voc = nn.Linear(args.s2s["d_hid_dec"], args.max_word_v_size) - return decoder, hid2voc - - -def build_qa_module(task, d_inp, project_before_pooling, params): - """ Build a simple QA module that - 1) pools representations (either of the joint (context, question, answer) or individually - 2) projects down to two logits - 3) classifier - - This module models each question-answer pair _individually_ """ - pooler = Pooler( - project=project_before_pooling, - d_inp=d_inp, - d_proj=params["d_proj"], - pool_type=params["pool_type"], - ) - d_out = params["d_proj"] if project_before_pooling else d_inp - classifier = Classifier.from_params(d_out, 2, params) - return SingleClassifier(pooler, classifier) - - -class MultiTaskModel(nn.Module): - """ - Giant model with task-specific components and a shared word and sentence encoder. - This class samples the tasks passed in pretrained_tasks, and adds task specific components - to the model. - """ - - def __init__(self, args, sent_encoder, vocab, cuda_devices): - """ Args: sentence encoder """ - super(MultiTaskModel, self).__init__() - self.sent_encoder = sent_encoder - self._cuda_device = cuda_devices - self.vocab = vocab - self.utilization = Average() if args.track_batch_utilization else None - self.elmo = args.input_module == "elmo" - self.uses_pair_embedding = input_module_uses_pair_embedding(args.input_module) - self.uses_mirrored_pair = input_module_uses_mirrored_pair(args.input_module) - self.project_before_pooling = not ( - input_module_uses_transformers(args.input_module) - and args.transfer_paradigm == "finetune" - ) # Rough heuristic. TODO: Make this directly user-controllable. - self.sep_embs_for_skip = args.sep_embs_for_skip - - def forward(self, task, batch, predict=False): - """ - Pass inputs to correct forward pass - Args: - - task (tasks.Task): task for which batch is drawn - - batch (Dict[str:Dict[str:Tensor]]): dictionary of (field, indexing) pairs, - where indexing is a dict of the index namespace and the actual indices. - - predict (Bool): passed to task specific forward(). If true, forward() - should return predictions. - Returns: - - out: dictionary containing task outputs and loss if label was in batch - """ - if self.utilization is not None: - if "input1" in batch: - self.utilization(get_batch_utilization(batch["input1"])) - elif "input" in batch: - self.utilization(get_batch_utilization(batch["input"])) - if isinstance(task, SingleClassificationTask): - out = self._single_sentence_forward(batch, task, predict) - elif isinstance(task, GLUEDiagnosticTask): - out = self._nli_diagnostic_forward(batch, task, predict) - elif isinstance( - task, (PairClassificationTask, PairRegressionTask, PairOrdinalRegressionTask) - ): - out = self._pair_sentence_forward(batch, task, predict) - elif isinstance(task, MaskedLanguageModelingTask): - out = self._masked_lm_forward(batch, task, predict) - elif isinstance(task, AutoregressiveLanguageModelingTask): - if isinstance(self.sent_encoder._phrase_layer, ONLSTMStack) or isinstance( - self.sent_encoder._phrase_layer, PRPN - ): - out = self._lm_only_lr_forward(batch, task) - else: - out = self._lm_forward(batch, task, predict) - elif isinstance(task, TaggingTask): - out = self._tagger_forward(batch, task, predict) - elif isinstance(task, MultipleChoiceTask): - out = self._mc_forward(batch, task, predict) - elif isinstance(task, EdgeProbingTask): - # Just get embeddings and invoke task module. - word_embs_in_context, sent_mask = self.sent_encoder(batch["input1"], task) - module = getattr(self, "%s_mdl" % task.name) - out = module.forward( - batch=batch, - word_embs_in_context=word_embs_in_context, - sent_mask=sent_mask, - task=task, - predict=predict, - ) - elif isinstance(task, SequenceGenerationTask): - out = self._seq_gen_forward(batch, task, predict) - elif isinstance(task, (MultiRCTask, ReCoRDTask)): - out = self._multiple_choice_reading_comprehension_forward(batch, task, predict) - elif isinstance(task, SpanClassificationTask): - out = self._span_forward(batch, task, predict) - elif isinstance(task, SpanPredictionTask): - out = self._span_prediction_forward(batch, task, predict) - elif isinstance(task, SentenceOrderTask): - out = self._sop_forward(batch, task, predict) - else: - raise ValueError("Task-specific components not found!") - return out - - def _get_task_params(self, task_name): - """ Get task-specific Params, as set in build_module(). """ - return getattr(self, "%s_task_params" % task_name) - - def _get_classifier(self, task): - """ Get task-specific classifier, as set in build_module(). """ - # TODO: replace this logic with task._classifier_name? - task_params = self._get_task_params(task.name) - use_clf = task_params["use_classifier"] - if use_clf in [None, "", "none"]: - use_clf = task.name # default if not set - return getattr(self, "%s_mdl" % use_clf) - - def _single_sentence_forward(self, batch, task, predict): - out = {} - - # embed the sentence - word_embs_in_context, sent_mask = self.sent_encoder(batch["input1"], task) - # pass to a task specific classifier - classifier = self._get_classifier(task) - logits = classifier(word_embs_in_context, sent_mask) - out["logits"] = logits - out["n_exs"] = get_batch_size(batch, self._cuda_device) - - if "labels" in batch: # means we should compute loss - if batch["labels"].dim() == 0: - labels = batch["labels"].unsqueeze(0) - elif batch["labels"].dim() == 1: - labels = batch["labels"] - else: - labels = batch["labels"].squeeze(-1) - out["loss"] = format_output(F.cross_entropy(logits, labels), self._cuda_device) - out["labels"] = labels - - if predict: - if isinstance(task, RegressionTask): - if logits.ndimension() > 1: - assert ( - logits.ndimension() == 2 and logits[-1] == 1 - ), "Invalid regression prediction dimensions!" - logits = logits.squeeze(-1) - out["preds"] = logits - else: - _, out["preds"] = logits.max(dim=1) - return out - - def _nli_diagnostic_forward(self, batch, task, predict): - out = {} - - # embed the sentence - classifier = self._get_classifier(task) - if self.uses_pair_embedding: - sent, mask = self.sent_encoder(batch["inputs"], task) - logits = classifier(sent, mask) - else: - sent1, mask1 = self.sent_encoder(batch["input1"], task) - sent2, mask2 = self.sent_encoder(batch["input2"], task) - logits = classifier(sent1, sent2, mask1, mask2) - out["logits"] = logits - out["n_exs"] = get_batch_size(batch, self._cuda_device) - - if "labels" in batch: - if batch["labels"].dim() == 0: - labels = batch["labels"].unsqueeze(0) - elif batch["labels"].dim() == 1: - labels = batch["labels"] - else: - labels = batch["labels"].squeeze(-1) - out["loss"] = F.cross_entropy(logits, labels) - - if predict: - _, predicted = logits.max(dim=1) - out["preds"] = predicted - - return out - - def _span_forward(self, batch, task, predict): - sent_embs, sent_mask = self.sent_encoder(batch["input1"], task) - module = getattr(self, "%s_mdl" % task.name) - out = module.forward(batch, sent_embs, sent_mask, task, predict, self._cuda_device) - return out - - def _span_prediction_forward(self, batch, task, predict): - sent_embs, sent_mask = self.sent_encoder(batch["inputs"], task) - module = getattr(self, "%s_mdl" % task.name) - logits_dict = module.forward(sent_embs, sent_mask) - out = { - "logits": logits_dict, - "n_exs": get_batch_size(batch, self._cuda_device), - "start_loss": F.cross_entropy( - input=logits_dict["span_start"], target=batch["span_start"].long().squeeze(dim=1) - ), - "end_loss": F.cross_entropy( - input=logits_dict["span_end"], target=batch["span_end"].long().squeeze(dim=1) - ), - } - out["loss"] = (out["start_loss"] + out["end_loss"]) / 2 - - # Form string predictions - pred_span_start = torch.argmax(logits_dict["span_start"], dim=1) - pred_span_end = torch.argmax(logits_dict["span_end"], dim=1) - - if predict: - out["preds"] = {"span_start": pred_span_start, "span_end": pred_span_end} - return out - - def _pair_sentence_forward(self, batch, task, predict): - out = {} - classifier = self._get_classifier(task) - if isinstance(task, (MRPCTask, STSBTask, QQPTask)) and self.uses_mirrored_pair: - # Mirrored pair is a trick used by GPT-like models in similarity tasks - # TODO: Wic also falls into this type, although GPT paper didn't experiment - # with this task - sent, mask = self.sent_encoder(batch["inputs"], task) - sent_m, mask_m = self.sent_encoder(batch["inputs_m"], task) - logits = classifier(sent, mask) + classifier(sent_m, mask_m) - elif self.uses_pair_embedding: - sent, mask = self.sent_encoder(batch["inputs"], task) - # special case for WiC b/c we want to add representations of particular tokens - if isinstance(task, WiCTask): - logits = classifier(sent, mask, [batch["idx1"], batch["idx2"]]) - else: - logits = classifier(sent, mask) - else: - sent1, mask1 = self.sent_encoder(batch["input1"], task) - sent2, mask2 = self.sent_encoder(batch["input2"], task) - if isinstance(task, WiCTask): - logits = classifier(sent1, sent2, mask1, mask2, [batch["idx1"]], [batch["idx2"]]) - else: - logits = classifier(sent1, sent2, mask1, mask2) - out["n_exs"] = get_batch_size(batch, self._cuda_device) - if "labels" in batch: - labels = batch["labels"] - labels = labels.squeeze(-1) if len(labels.size()) > 1 else labels - if isinstance(task, RegressionTask): - logits = logits.squeeze(-1) if len(logits.size()) > 1 else logits - out["loss"] = F.mse_loss(logits, labels) - labels = labels.detach() - logits = logits.detach() - else: - out["loss"] = F.cross_entropy(logits, labels) - out["labels"] = labels - - out["loss"] = format_output(out["loss"], self._cuda_device) - out["logits"] = logits - if predict: - if isinstance(task, RegressionTask): - if logits.ndimension() > 1: - assert ( - logits.ndimension() == 2 and logits[-1] == 1 - ), "Invalid regression prediction dimensions!" - logits = logits.squeeze(-1) - out["preds"] = logits - else: - _, out["preds"] = logits.max(dim=1) - return out - - def _seq_gen_forward(self, batch, task, predict): - """ For sequence generation tasks """ - out = {} - sent, sent_mask = self.sent_encoder(batch["inputs"], task) - out["n_exs"] = get_batch_size(batch, self._cuda_device) - - decoder = getattr(self, "%s_decoder" % task.name) - out.update(decoder.forward(sent, sent_mask, batch["targs"], generate=predict)) - # Loss is not computed during generation. - if "loss" in out: - task.scorer1(out["loss"].item()) - - if "targs" in batch: - # logits: batch_size * seq_len * tgt_voc_size - target = batch["targs"]["words"][:, 1:].contiguous() - target_mask = out["target_mask"] - - assert "predictions" in out - out["logits"] = None - out["labels"] = target - - return out - - def _tagger_forward(self, batch: dict, task: TaggingTask, predict: bool) -> dict: - """ - This function is for sequence tagging (one-to-one mapping between words and tags). - Args: - batch: a dict of inputs and target tags - task: TaggingTask - predict: (boolean) predict mode (not supported) - Returns - out: (dict) - - 'logits': output layer, dimension: [batchSize * task.max_seq_len, task.num_tags] - - 'loss': size average CE loss - """ - out = {} - # batch[inputs] only has one item - b_size, seq_len = list(batch["inputs"].values())[0].size() - seq_len -= 2 - # Note: we are assuming there is one beginning and one ending token, when that no longer - # holds, we need to refactor this by adjusting mask according to boundry function - out["n_exs"] = get_batch_size(batch, self._cuda_device) - sent, mask = self.sent_encoder(batch["inputs"], task) - hid2tag = self._get_classifier(task) - logits = hid2tag(sent[:, 1:-1, :]).view(b_size * seq_len, -1) - targs = batch["targs"]["words"][:, :seq_len].contiguous().view(-1) - if "mask" in batch: - # Prevent backprop for tags generated for tokenization-introduced tokens - # such as word boundaries - batch_mask = batch["mask"][:, :seq_len] - keep_idxs = torch.nonzero(batch_mask.contiguous().view(-1).data).squeeze() - logits = logits.index_select(0, keep_idxs) - targs = targs.index_select(0, keep_idxs) - out["labels"] = targs - out["logits"] = logits - out["loss"] = format_output(F.cross_entropy(logits, targs), self._cuda_device) - return out - - def _lm_forward(self, batch, task, predict): - """Forward pass for LM model - Args: - batch: indexed input data - task: (Task obejct) - predict: (boolean) predict mode (not supported) - return: - out: (dict) - - 'logits': output layer, dimension: [batchSize * timeSteps * 2, outputDim] - first half: [:batchSize*timeSteps, outputDim] is output layer from - forward layer - second half: [batchSize*timeSteps:, outputDim] is output layer from - backward layer - - 'loss': size average CE loss - """ - out = {} - sent_encoder = self.sent_encoder - assert_for_log( - isinstance(sent_encoder._phrase_layer, BiLMEncoder), - "Not using LM for language modeling task!", - ) - assert_for_log( - "targs" in batch and "words" in batch["targs"], "Batch missing target words!" - ) - pad_idx = self.vocab.get_token_index(self.vocab._padding_token, "tokens") - b_size, seq_len = batch["targs"]["words"].size() - n_pad = batch["targs"]["words"].eq(pad_idx).sum().item() - out["n_exs"] = format_output(((b_size * seq_len - n_pad) * 2), self._cuda_device) - - sent, mask = sent_encoder(batch["input"], task) - sent = sent.masked_fill(1 - mask.byte(), 0) # avoid NaNs - - # Split encoder outputs by direction - split = int(self.sent_encoder._phrase_layer.get_output_dim() / 2) - fwd, bwd = sent[:, :, :split], sent[:, :, split : split * 2] - if split * 2 < sent.size(2): # skip embeddings - out_embs = sent[:, :, split * 2 :] - fwd = torch.cat([fwd, out_embs], dim=2) - bwd = torch.cat([bwd, out_embs], dim=2) - - # Forward and backward logits and targs - hid2voc = getattr(self, "%s_hid2voc" % task.name) - logits_fwd = hid2voc(fwd).view(b_size * seq_len, -1) - logits_bwd = hid2voc(bwd).view(b_size * seq_len, -1) - logits = torch.cat([logits_fwd, logits_bwd], dim=0) - out["logits"] = logits - trg_fwd = batch["targs"]["words"].view(-1) - trg_bwd = batch["targs_b"]["words"].view(-1) - targs = torch.cat([trg_fwd, trg_bwd], dim=0) - assert logits.size(0) == targs.size(0), "Number of logits and targets differ!" - out["loss"] = format_output( - F.cross_entropy(logits, targs, ignore_index=pad_idx), self._cuda_device - ) - task.scorer1(out["loss"].item()) - if predict: - pass - return out - - def _masked_lm_forward(self, batch, task, predict): - """ - We currently only support RoBERTa-style dynamic masking, with the exact - setup and parameters as RoBERTa. - """ - out = {} - tokenizer_name = self.sent_encoder._text_field_embedder.input_module - text_embedder = self.sent_encoder._text_field_embedder - vocab_size = text_embedder.model.embeddings.word_embeddings.num_embeddings - input_key = text_embedder.tokenizer_required - mask_idx = text_embedder._mask_id - b_size, seq_len = batch["targs"].size() - inputs = batch["input"][input_key] - labels = batch["targs"] - inputs, labels, _, _, _, _ = task.mlm_dynamic_masking( - inputs, labels, mask_idx, tokenizer_name, self.sent_encoder - ) - batch["input"][input_key] = inputs - sent_embs, sent_mask = self.sent_encoder(batch["input"], task) - module = getattr(self, "%s_mdl" % task.name) - logits = module.forward(sent_embs) - out["logits"] = logits - out["loss"] = F.cross_entropy(logits.view(-1, vocab_size), labels.view(-1)) - out["n_exs"] = format_output(b_size, self._cuda_device) - return out - - def _mc_forward(self, batch, task, predict): - """ Forward for a multiple choice question answering task """ - out = {} - - logits = [] - module = self._get_classifier(task) - if self.uses_pair_embedding: - for choice_idx in range(task.n_choices): - sent, mask = self.sent_encoder(batch["choice%d" % choice_idx], task) - logit = module(sent, mask) - logits.append(logit) - else: - ctx, ctx_mask = self.sent_encoder(batch["question"], task) - for choice_idx in range(task.n_choices): - sent, mask = self.sent_encoder(batch["choice%d" % choice_idx], task) - inp = torch.cat([ctx, sent], dim=1) - inp_mask = torch.cat([ctx_mask, mask], dim=1) - logit = module(inp, inp_mask) - logits.append(logit) - logits = torch.cat(logits, dim=1) - out["logits"] = logits - out["n_exs"] = get_batch_size(batch, self._cuda_device, keyword="choice0") - if "label" in batch: - labels = batch["label"] - out["loss"] = format_output(F.cross_entropy(logits, labels), self._cuda_device) - - if predict: - out["preds"] = logits.argmax(dim=-1) - return out - - def _lm_only_lr_forward(self, batch, task): - """Only left to right pass for LM model - non-bidirectional models. - Used for language modeling training only in one direction. - Args: - batch: indexed input data - task: (Task obejct) - return: - out: (dict) - - 'logits': output layer, dimension: [batchSize * timeSteps, outputDim] - is output layer from forward layer - - 'loss': size average CE loss - """ - - out = {} - assert_for_log( - "targs" in batch and "words" in batch["targs"], "Batch missing target words!" - ) - pad_idx = self.vocab.get_token_index(self.vocab._padding_token, "tokens") - b_size, seq_len = batch["targs"]["words"].size() - # pad_idx is the token used to pad till max_seq_len - n_pad = batch["targs"]["words"].eq(pad_idx).sum().item() - # No of examples: only left to right, every unit in the sequence length is - # a training example only once. - out["n_exs"] = format_output(b_size * seq_len - n_pad, self._cuda_device) - sent, mask = self.sent_encoder(batch["input"], task) - sent = sent.masked_fill(1 - mask.byte(), 0) - hid2voc = getattr(self, "%s_hid2voc" % task.name) - logits = hid2voc(sent).view(b_size * seq_len, -1) - out["logits"] = logits - trg_fwd = batch["targs"]["words"].view(-1) - assert logits.size(0) == trg_fwd.size(0), "Number of logits and targets differ!" - out["loss"] = format_output( - F.cross_entropy(logits, trg_fwd, ignore_index=pad_idx), self._cuda_device - ) - task.scorer1(out["loss"].item()) - return out - - def _multiple_choice_reading_comprehension_forward(self, batch, task, predict): - """ Forward call for multiple choice (selecting from a fixed set of answers) - reading comprehension (have a supporting paragraph). - - Batch has a tensor of shape (n_questions, n_answers, n_tokens) - """ - out = {} - classifier = self._get_classifier(task) - if self.uses_pair_embedding: - # if using BERT/XLNet, we concatenate the passage, question, and answer - inp = batch["psg_qst_ans"] - ex_embs, ex_mask = self.sent_encoder(inp, task) - logits = classifier(ex_embs, ex_mask) - out["n_exs"] = get_batch_size(batch, self._cuda_device, keyword="psg_qst_ans") - else: - # else, we embed each independently and concat them - psg_emb, psg_mask = self.sent_encoder(batch["psg"], task) - qst_emb, qst_mask = self.sent_encoder(batch["qst"], task) - - if "ans" in batch: # most QA tasks, e.g. MultiRC have explicit answer fields - ans_emb, ans_mask = self.sent_encoder(batch["ans"], task) - inp = torch.cat([psg_emb, qst_emb, ans_emb], dim=1) - inp_mask = torch.cat([psg_mask, qst_mask, ans_mask], dim=1) - out["n_exs"] = get_batch_size(batch, self._cuda_device, keyword="ans") - else: # ReCoRD inserts answer into the query - inp = torch.cat([psg_emb, qst_emb], dim=1) - inp_mask = torch.cat([psg_mask, qst_mask], dim=1) - out["n_exs"] = get_batch_size(batch, self._cuda_device, keyword="qst") - - logits = classifier(inp, inp_mask) - out["logits"] = logits - if "label" in batch: - out["loss"] = format_output(F.cross_entropy(logits, batch["label"]), self._cuda_device) - - if predict: - if isinstance(task, ReCoRDTask): - # For ReCoRD, we want the logits to make - # predictions across answer choices - # (which are spread across batches) - out["preds"] = logits - else: - out["preds"] = logits.argmax(dim=-1) - - return out - - def get_elmo_mixing_weights(self, tasks=[]): - """ Get elmo mixing weights from text_field_embedder. Gives warning when fails. - args: - - tasks (List[Task]): list of tasks that we want to get ELMo scalars for. - returns: - - params Dict[str:float]: dictionary maybe layers to scalar params - """ - params = {} - if self.elmo: - if not self.sep_embs_for_skip: - tasks = [None] - else: - tasks = [None] + tasks - for task in tasks: - if task: - params[task._classifier_name] = get_elmo_mixing_weights( - self.sent_encoder._text_field_embedder, task=task - ) - else: - params["@pretrain@"] = get_elmo_mixing_weights( - self.sent_encoder._text_field_embedder, task=None - ) - return params - - -def input_module_uses_pair_embedding(input_module): - """ - This function tells whether the input module concatenate the two sentences in a pair when - running on pair tasks, like what GPT / BERT do on MNLI. - It seems redundant now, but it allows us to load similar models from other sources later on - """ - from jiant.huggingface_transformers_interface import input_module_uses_transformers - - return input_module_uses_transformers(input_module) - - -def input_module_uses_mirrored_pair(input_module): - """ - This function tells whether the input model uses raw pair and mirrored pair simutaneously when - running on symmetrical pair tasks, like what GPT do on STS-B - """ - return ( - input_module.startswith("openai-gpt") - or input_module.startswith("gpt2") - or input_module.startswith("transfo-xl-") - ) diff --git a/jiant/modules/attention.py b/jiant/modules/attention.py deleted file mode 100644 index 6780f84cd..000000000 --- a/jiant/modules/attention.py +++ /dev/null @@ -1,25 +0,0 @@ -import torch -from torch import nn -from overrides import overrides -from allennlp.modules.attention import Attention - - -@Attention.register("Bahdanau") -class BahdanauAttention(Attention): - def __init__( - self, tensor_1_dim: int, tensor_2_dim: int, att_hid_size: int = 100, normalize: bool = True - ) -> None: - super().__init__(normalize) - - self.linear_1 = nn.Linear(tensor_1_dim + tensor_2_dim, att_hid_size) - self.tanh = nn.Tanh() - self.linear_2 = nn.Linear(att_hid_size, 1) - - @overrides - def _forward_internal(self, vector: torch.Tensor, matrix: torch.Tensor) -> torch.Tensor: - vector_large = vector.unsqueeze(1).expand([-1, matrix.shape[1], -1]) - matrix_vector = torch.cat([matrix, vector_large], dim=2) - forward_1 = self.tanh(self.linear_1(matrix_vector)) - forward_2 = self.linear_2(forward_1) - - return forward_2.squeeze(2) diff --git a/jiant/modules/attn_pair_encoder.py b/jiant/modules/attn_pair_encoder.py deleted file mode 100644 index edfeb9091..000000000 --- a/jiant/modules/attn_pair_encoder.py +++ /dev/null @@ -1,95 +0,0 @@ -# StackedSelfAttentionEncoder -import torch -from allennlp.modules import Seq2SeqEncoder -from allennlp.modules.matrix_attention import DotProductMatrixAttention -from allennlp.nn import InitializerApplicator, util -from allennlp.models.model import Model - - -class AttnPairEncoder(Model): - """ - Simplified version of BiDAF. - - Parameters - ---------- - vocab : ``Vocabulary`` - modeling_layer : ``Seq2SeqEncoder`` - The encoder (with its own internal stacking) that we will use in after the bidirectional - attention. - dropout : ``float``, optional (default=0.2) - If greater than 0, we will apply dropout with this probability after all encoders (pytorch - LSTMs do not apply dropout to their last layer). - mask_lstms : ``bool``, optional (default=True) - If ``False``, we will skip passing the mask to the LSTM layers. This gives a ~2x speedup, - with only a slight performance decrease, if any. We haven't experimented much with this - yet, but have confirmed that we still get very similar performance with much faster - training times. We still use the mask for all softmaxes, but avoid the shuffling that's - required when using masking with pytorch LSTMs. - initializer : ``InitializerApplicator``, optional (default=``InitializerApplicator()``) - Used to initialize the model parameters. - regularizer : ``RegularizerApplicator``, optional (default=``None``) - If provided, will be used to calculate the regularization penalty during training. - """ - - def __init__( - self, - vocab, - modeling_layer, - dropout=0.2, - mask_lstms=True, - initializer=InitializerApplicator(), - ): - super(AttnPairEncoder, self).__init__(vocab) - - self._matrix_attention = DotProductMatrixAttention() - self._modeling_layer = modeling_layer - self.pad_idx = vocab.get_token_index(vocab._padding_token) - - d_out_model = modeling_layer.get_output_dim() - self.output_dim = d_out_model - - self._dropout = torch.nn.Dropout(p=dropout) if dropout > 0 else lambda x: x - self._mask_lstms = mask_lstms - - initializer(self) - - def forward(self, s1, s2, s1_mask, s2_mask): # pylint: disable=arguments-differ - # Similarity matrix - # Shape: (batch_size, s2_length, s1_length) - similarity_mat = self._matrix_attention(s2, s1) - - # s2 representation - # Shape: (batch_size, s2_length, s1_length) - s2_s1_attn = util.masked_softmax(similarity_mat, s1_mask) - # Shape: (batch_size, s2_length, encoding_dim) - s2_s1_vectors = util.weighted_sum(s1, s2_s1_attn) - # batch_size, seq_len, 4*enc_dim - s2_w_context = torch.cat([s2, s2_s1_vectors], 2) - - # s1 representation, using same attn method as for the s2 - # representation - s1_s2_attn = util.masked_softmax(similarity_mat.transpose(1, 2).contiguous(), s2_mask) - # Shape: (batch_size, s1_length, encoding_dim) - s1_s2_vectors = util.weighted_sum(s2, s1_s2_attn) - s1_w_context = torch.cat([s1, s1_s2_vectors], 2) - - modeled_s1 = self._dropout(self._modeling_layer(s1_w_context, s1_mask)) - modeled_s2 = self._dropout(self._modeling_layer(s2_w_context, s2_mask)) - return modeled_s1, modeled_s2 - - @classmethod - def from_params(cls, vocab, params): - """ Initialize from a Params object """ - modeling_layer = Seq2SeqEncoder.from_params(params.pop("modeling_layer")) - dropout = params.pop("dropout", 0.2) - initializer = InitializerApplicator.from_params(params.pop("initializer", [])) - - mask_lstms = params.pop("mask_lstms", True) - params.assert_empty(cls.__name__) - return cls( - vocab=vocab, - modeling_layer=modeling_layer, - dropout=dropout, - mask_lstms=mask_lstms, - initializer=initializer, - ) diff --git a/jiant/modules/bilm_encoder.py b/jiant/modules/bilm_encoder.py deleted file mode 100644 index aa58640b1..000000000 --- a/jiant/modules/bilm_encoder.py +++ /dev/null @@ -1,13 +0,0 @@ -from allennlp.modules.elmo_lstm import ElmoLstm - - -class BiLMEncoder(ElmoLstm): - """Wrapper around BiLM to give it an interface to comply with SentEncoder - See base class: ElmoLstm - """ - - def get_input_dim(self): - return self.input_size - - def get_output_dim(self): - return self.hidden_size * 2 diff --git a/jiant/modules/bow_sentence_encoder.py b/jiant/modules/bow_sentence_encoder.py deleted file mode 100644 index ef0b3a51e..000000000 --- a/jiant/modules/bow_sentence_encoder.py +++ /dev/null @@ -1,29 +0,0 @@ -from allennlp.models.model import Model -from allennlp.nn import InitializerApplicator, util - - -class BoWSentEncoder(Model): - """ Bag-of-words sentence encoder """ - - def __init__(self, vocab, text_field_embedder, initializer=InitializerApplicator()): - super(BoWSentEncoder, self).__init__(vocab) - - self._text_field_embedder = text_field_embedder - self.output_dim = text_field_embedder.get_output_dim() - initializer(self) - - def forward(self, sent, task): - # pylint: disable=arguments-differ - """ - Args: - - sent (Dict[str, torch.LongTensor]): From a ``TextField``. - - task: Ignored. - - Returns - - word_embs (torch.FloatTensor): (b_size, seq_len, d_emb) - TODO: check what the padded values in word_embs are (0 or -inf or something else?) - - word_mask (torch.FloatTensor): (b_size, seq_len, d_emb); all 0/1s - """ - word_embs = self._text_field_embedder(sent) - word_mask = util.get_text_field_mask(sent).float() - return word_embs, word_mask # need to get # nonzero elts diff --git a/jiant/modules/cove b/jiant/modules/cove deleted file mode 160000 index b17b4c18a..000000000 --- a/jiant/modules/cove +++ /dev/null @@ -1 +0,0 @@ -Subproject commit b17b4c18ac9793f08de9ca7814dac5e54af4c5bb diff --git a/jiant/modules/edge_probing.py b/jiant/modules/edge_probing.py deleted file mode 100644 index fce4606bd..000000000 --- a/jiant/modules/edge_probing.py +++ /dev/null @@ -1,203 +0,0 @@ -# Implementation of edge probing module. -from typing import Dict - -import torch -import torch.nn as nn -import torch.nn.functional as F -from allennlp.modules.span_extractors import EndpointSpanExtractor, SelfAttentiveSpanExtractor - -from jiant.tasks.edge_probing import EdgeProbingTask -from jiant.modules.simple_modules import Classifier - - -class EdgeClassifierModule(nn.Module): - """ Build edge classifier components as a sub-module. - - Use same classifier code as build_single_sentence_module, - except instead of whole-sentence pooling we'll use span1 and span2 indices - to extract span representations, and use these as input to the classifier. - - This works in the current form, but with some provisos: - - Only considers the explicit set of spans in inputs; does not consider - all other spans as negatives. (So, this won't work for argument - _identification_ yet.) - - TODO: consider alternate span-pooling operators: max or mean-pooling, - or SegRNN. - - TODO: add span-expansion to negatives, one of the following modes: - - all-spans (either span1 or span2), treating not-seen as negative - - all-tokens (assuming span1 and span2 are length-1), e.g. for - dependency parsing - - batch-negative (pairwise among spans seen in batch, where not-seen - are negative) - """ - - def _make_span_extractor(self): - if self.span_pooling == "attn": - return SelfAttentiveSpanExtractor(self.proj_dim) - else: - return EndpointSpanExtractor(self.proj_dim, combination=self.span_pooling) - - def _make_cnn_layer(self, d_inp): - """Make a CNN layer as a projection of local context. - - CNN maps [batch_size, max_len, d_inp] - to [batch_size, max_len, proj_dim] with no change in length. - """ - k = 1 + 2 * self.cnn_context - padding = self.cnn_context - return nn.Conv1d( - d_inp, - self.proj_dim, - kernel_size=k, - stride=1, - padding=padding, - dilation=1, - groups=1, - bias=True, - ) - - def __init__(self, task, d_inp: int, task_params): - super(EdgeClassifierModule, self).__init__() - # Set config options needed for forward pass. - self.loss_type = task_params["cls_loss_fn"] - self.span_pooling = task_params["cls_span_pooling"] - self.cnn_context = task_params["edgeprobe_cnn_context"] - self.is_symmetric = task_params["edgeprobe_symmetric"] - self.single_sided = task.single_sided - - self.proj_dim = task_params["d_hid"] - # Separate projection for span1, span2. - # Convolution allows using local context outside the span, with - # cnn_context = 0 behaving as a per-word linear layer. - # Use these to reduce dimensionality in case we're enumerating a lot of - # spans - we want to do this *before* extracting spans for greatest - # efficiency. - self.proj1 = self._make_cnn_layer(d_inp) - if self.is_symmetric or self.single_sided: - # Use None as dummy padding for readability, - # so that we can index projs[1] and projs[2] - self.projs = nn.ModuleList([None, self.proj1, self.proj1]) - else: - # Separate params for span2 - self.proj2 = self._make_cnn_layer(d_inp) - self.projs = nn.ModuleList([None, self.proj1, self.proj2]) - - # Span extractor, shared for both span1 and span2. - self.span_extractor1 = self._make_span_extractor() - if self.is_symmetric or self.single_sided: - self.span_extractors = nn.ModuleList([None, self.span_extractor1, self.span_extractor1]) - else: - self.span_extractor2 = self._make_span_extractor() - self.span_extractors = nn.ModuleList([None, self.span_extractor1, self.span_extractor2]) - - # Classifier gets concatenated projections of span1, span2 - clf_input_dim = self.span_extractors[1].get_output_dim() - if not self.single_sided: - clf_input_dim += self.span_extractors[2].get_output_dim() - self.classifier = Classifier.from_params(clf_input_dim, task.n_classes, task_params) - - def forward( - self, - batch: Dict, - word_embs_in_context: torch.Tensor, - sent_mask: torch.Tensor, - task: EdgeProbingTask, - predict: bool, - ) -> Dict: - """ Run forward pass. - - Expects batch to have the following entries: - 'batch1' : [batch_size, max_len, ??] - 'labels' : [batch_size, num_targets] of label indices - 'span1s' : [batch_size, num_targets, 2] of spans - 'span2s' : [batch_size, num_targets, 2] of spans - - 'labels', 'span1s', and 'span2s' are padded with -1 along second - (num_targets) dimension. - - Args: - batch: dict(str -> Tensor) with entries described above. - word_embs_in_context: [batch_size, max_len, repr_dim] Tensor - sent_mask: [batch_size, max_len, 1] Tensor of {0,1} - task: EdgeProbingTask - predict: whether or not to generate predictions - - Returns: - out: dict(str -> Tensor) - """ - out = {} - - # Apply projection CNN layer for each span. - word_embs_in_context_t = word_embs_in_context.transpose(1, 2) # needed for CNN layer - - se_proj1 = self.projs[1](word_embs_in_context_t).transpose(2, 1).contiguous() - if not self.single_sided: - se_proj2 = self.projs[2](word_embs_in_context_t).transpose(2, 1).contiguous() - - # Span extraction. - # [batch_size, num_targets] bool - span_mask = batch["span1s"][:, :, 0] != -1 - out["mask"] = span_mask - total_num_targets = span_mask.sum() - out["n_targets"] = total_num_targets - out["n_exs"] = total_num_targets # used by trainer.py - - _kw = dict(sequence_mask=sent_mask.long(), span_indices_mask=span_mask.long()) - # span1_emb and span2_emb are [batch_size, num_targets, span_repr_dim] - span1_emb = self.span_extractors[1](se_proj1, batch["span1s"], **_kw) - if not self.single_sided: - span2_emb = self.span_extractors[2](se_proj2, batch["span2s"], **_kw) - span_emb = torch.cat([span1_emb, span2_emb], dim=2) - else: - span_emb = span1_emb - - # [batch_size, num_targets, n_classes] - logits = self.classifier(span_emb) - out["logits"] = logits - - # Compute loss if requested. - if "labels" in batch: - # Labels is [batch_size, num_targets, n_classes], - # with k-hot encoding provided by AllenNLP's MultiLabelField. - # Flatten to [total_num_targets, ...] first. - out["loss"] = self.compute_loss(logits[span_mask], batch["labels"][span_mask], task) - - if predict: - out["preds"] = self.get_predictions(logits) - - return out - - def get_predictions(self, logits: torch.Tensor): - """Return class probabilities, same shape as logits. - - Args: - logits: [batch_size, num_targets, n_classes] - - Returns: - probs: [batch_size, num_targets, n_classes] - """ - if self.loss_type == "sigmoid": - return torch.sigmoid(logits) - else: - raise ValueError("Unsupported loss type '%s' " "for edge probing." % self.loss_type) - - def compute_loss(self, logits: torch.Tensor, labels: torch.Tensor, task: EdgeProbingTask): - """ Compute loss & eval metrics. - - Expect logits and labels to be already "selected" for good targets, - i.e. this function does not do any masking internally. - - Args: - logits: [total_num_targets, n_classes] Tensor of float scores - labels: [total_num_targets, n_classes] Tensor of sparse binary targets - - Returns: - loss: scalar Tensor - """ - - if self.loss_type == "sigmoid": - return F.binary_cross_entropy(torch.sigmoid(logits), labels.float()) - else: - raise ValueError("Unsupported loss type '%s' " "for edge probing." % self.loss_type) diff --git a/jiant/modules/elmo_character_encoder.py b/jiant/modules/elmo_character_encoder.py deleted file mode 100644 index 417996549..000000000 --- a/jiant/modules/elmo_character_encoder.py +++ /dev/null @@ -1,232 +0,0 @@ -import torch -import numpy -import json -import h5py -from allennlp.modules import Highway -from allennlp.common.checks import ConfigurationError -from allennlp.common.file_utils import cached_path -from allennlp.data.token_indexers.elmo_indexer import ELMoCharacterMapper -from allennlp.nn.util import add_sentence_boundary_token_ids - - -class ElmoCharacterEncoder(torch.nn.Module): - """Just the ELMo character encoder that we ripped so we could use alone. - - Compute context sensitive token representation using pretrained biLM. - - This embedder has input character ids of size (batch_size, sequence_length, 50) - and returns (batch_size, sequence_length + 2, embedding_dim), where embedding_dim - is specified in the options file (typically 512). - - We add special entries at the beginning and end of each sequence corresponding - to and , the beginning and end of sentence tokens. - - Note: this is a lower level class useful for advanced usage. Most users should - use ``ElmoTokenEmbedder`` or ``allennlp.modules.Elmo`` instead. - - Parameters - ---------- - options_file : ``str`` - ELMo JSON options file - weight_file : ``str`` - ELMo hdf5 weight file - requires_grad: ``bool``, optional - If True, compute gradient of ELMo parameters for fine tuning. - - The relevant section of the options file is something like: - .. example-code:: - - .. code-block:: python - - {'char_cnn': { - 'activation': 'relu', - 'embedding': {'dim': 4}, - 'filters': [[1, 4], [2, 8], [3, 16], [4, 32], [5, 64]], - 'max_characters_per_token': 50, - 'n_characters': 262, - 'n_highway': 2 - } - } - """ - - def __init__(self, options_file, weight_file, requires_grad=False): - super(ElmoCharacterEncoder, self).__init__() - - with open(cached_path(options_file), "r") as fin: - self._options = json.load(fin) - self._weight_file = weight_file - - self.output_dim = self._options["lstm"]["projection_dim"] - self.requires_grad = requires_grad - - self._load_weights() - - # Cache the arrays for use in forward -- +1 due to masking. - self._beginning_of_sentence_characters = torch.from_numpy( - numpy.array(ELMoCharacterMapper.beginning_of_sentence_characters) + 1 - ) - self._end_of_sentence_characters = torch.from_numpy( - numpy.array(ELMoCharacterMapper.end_of_sentence_characters) + 1 - ) - - def get_output_dim(self): - return self.output_dim - - def forward(self, inputs): # pylint: disable=arguments-differ - """ - Compute context insensitive token embeddings for ELMo representations. - - Parameters - ---------- - inputs: ``torch.Tensor`` - Shape ``(batch_size, sequence_length, 50)`` of character ids representing the - current batch. - - Returns - ------- - Dict with keys: - ``'token_embedding'``: ``torch.Tensor`` - Shape ``(batch_size, sequence_length + 2, embedding_dim)`` tensor with context - insensitive token representations. - ``'mask'``: ``torch.Tensor`` - Shape ``(batch_size, sequence_length + 2)`` long tensor with sequence mask. - """ - # Add BOS/EOS - mask = ((inputs > 0).long().sum(dim=-1) > 0).long() - character_ids_with_bos_eos, mask_with_bos_eos = add_sentence_boundary_token_ids( - inputs, mask, self._beginning_of_sentence_characters, self._end_of_sentence_characters - ) - - # the character id embedding - max_chars_per_token = self._options["char_cnn"]["max_characters_per_token"] - # (batch_size * sequence_length, max_chars_per_token, embed_dim) - character_embedding = torch.nn.functional.embedding( - character_ids_with_bos_eos.view(-1, max_chars_per_token), self._char_embedding_weights - ) - - # run convolutions - cnn_options = self._options["char_cnn"] - if cnn_options["activation"] == "tanh": - activation = torch.nn.functional.tanh - elif cnn_options["activation"] == "relu": - activation = torch.nn.functional.relu - else: - raise ConfigurationError("Unknown activation") - - # (batch_size * sequence_length, embed_dim, max_chars_per_token) - character_embedding = torch.transpose(character_embedding, 1, 2) - convs = [] - for i in range(len(self._convolutions)): - conv = getattr(self, "char_conv_{}".format(i)) - convolved = conv(character_embedding) - # (batch_size * sequence_length, n_filters for this width) - convolved, _ = torch.max(convolved, dim=-1) - convolved = activation(convolved) - convs.append(convolved) - - # (batch_size * sequence_length, n_filters) - token_embedding = torch.cat(convs, dim=-1) - - # apply the highway layers (batch_size * sequence_length, n_filters) - token_embedding = self._highways(token_embedding) - - # final projection (batch_size * sequence_length, embedding_dim) - token_embedding = self._projection(token_embedding) - - # reshape to (batch_size, sequence_length, embedding_dim) - batch_size, sequence_length, _ = character_ids_with_bos_eos.size() - - return token_embedding.view(batch_size, sequence_length, -1)[:, 1:-1, :] - - def _load_weights(self): - self._load_char_embedding() - self._load_cnn_weights() - self._load_highway() - self._load_projection() - - def _load_char_embedding(self): - with h5py.File(cached_path(self._weight_file), "r") as fin: - char_embed_weights = fin["char_embed"][...] - - weights = numpy.zeros( - (char_embed_weights.shape[0] + 1, char_embed_weights.shape[1]), dtype="float32" - ) - weights[1:, :] = char_embed_weights - - self._char_embedding_weights = torch.nn.Parameter( - torch.FloatTensor(weights), requires_grad=self.requires_grad - ) - - def _load_cnn_weights(self): - cnn_options = self._options["char_cnn"] - filters = cnn_options["filters"] - char_embed_dim = cnn_options["embedding"]["dim"] - - convolutions = [] - for i, (width, num) in enumerate(filters): - conv = torch.nn.Conv1d( - in_channels=char_embed_dim, out_channels=num, kernel_size=width, bias=True - ) - # load the weights - with h5py.File(cached_path(self._weight_file), "r") as fin: - weight = fin["CNN"]["W_cnn_{}".format(i)][...] - bias = fin["CNN"]["b_cnn_{}".format(i)][...] - - w_reshaped = numpy.transpose(weight.squeeze(axis=0), axes=(2, 1, 0)) - if w_reshaped.shape != tuple(conv.weight.data.shape): - raise ValueError("Invalid weight file") - conv.weight.data.copy_(torch.FloatTensor(w_reshaped)) - conv.bias.data.copy_(torch.FloatTensor(bias)) - - conv.weight.requires_grad = self.requires_grad - conv.bias.requires_grad = self.requires_grad - - convolutions.append(conv) - self.add_module("char_conv_{}".format(i), conv) - - self._convolutions = convolutions - - def _load_highway(self): - # pylint: disable=protected-access - # the highway layers have same dimensionality as the number of cnn - # filters - cnn_options = self._options["char_cnn"] - filters = cnn_options["filters"] - n_filters = sum(f[1] for f in filters) - n_highway = cnn_options["n_highway"] - - # create the layers, and load the weights - self._highways = Highway(n_filters, n_highway, activation=torch.nn.functional.relu) - for k in range(n_highway): - # The AllenNLP highway is one matrix multplication with concatenation of - # transform and carry weights. - with h5py.File(cached_path(self._weight_file), "r") as fin: - # The weights are transposed due to multiplication order assumptions in tf - # vs pytorch (tf.matmul(X, W) vs pytorch.matmul(W, X)) - w_transform = numpy.transpose(fin["CNN_high_{}".format(k)]["W_transform"][...]) - # -1.0 since AllenNLP is g * x + (1 - g) * f(x) but tf is (1 - g) * x + g * f(x) - w_carry = -1.0 * numpy.transpose(fin["CNN_high_{}".format(k)]["W_carry"][...]) - weight = numpy.concatenate([w_transform, w_carry], axis=0) - self._highways._layers[k].weight.data.copy_(torch.FloatTensor(weight)) - self._highways._layers[k].weight.requires_grad = self.requires_grad - - b_transform = fin["CNN_high_{}".format(k)]["b_transform"][...] - b_carry = -1.0 * fin["CNN_high_{}".format(k)]["b_carry"][...] - bias = numpy.concatenate([b_transform, b_carry], axis=0) - self._highways._layers[k].bias.data.copy_(torch.FloatTensor(bias)) - self._highways._layers[k].bias.requires_grad = self.requires_grad - - def _load_projection(self): - cnn_options = self._options["char_cnn"] - filters = cnn_options["filters"] - n_filters = sum(f[1] for f in filters) - - self._projection = torch.nn.Linear(n_filters, self.output_dim, bias=True) - with h5py.File(cached_path(self._weight_file), "r") as fin: - weight = fin["CNN_proj"]["W_proj"][...] - bias = fin["CNN_proj"]["b_proj"][...] - self._projection.weight.data.copy_(torch.FloatTensor(numpy.transpose(weight))) - self._projection.bias.data.copy_(torch.FloatTensor(bias)) - - self._projection.weight.requires_grad = self.requires_grad - self._projection.bias.requires_grad = self.requires_grad diff --git a/jiant/modules/onlstm/ON_LSTM.py b/jiant/modules/onlstm/ON_LSTM.py deleted file mode 100644 index 7014dc86b..000000000 --- a/jiant/modules/onlstm/ON_LSTM.py +++ /dev/null @@ -1,222 +0,0 @@ -""" -Code for Ordered-Neurons Sentence encoder -Modules re-used from: https://github.com/yikangshen/Ordered-Neurons -""" -import numpy as np -import torch -import torch.nn as nn -import torch.nn.functional as f - -from jiant.utils.locked_dropout import LockedDropout - - -def embedded_dropout(embed, words, dropout=0.1, scale=None): - if dropout: - mask = embed.weight.data.new().resize_((embed.weight.size(0), 1)).bernoulli_( - 1 - dropout - ).expand_as(embed.weight) / (1 - dropout) - masked_embed_weight = mask * embed.weight - else: - masked_embed_weight = embed.weight - if scale: - masked_embed_weight = scale.expand_as(masked_embed_weight) * masked_embed_weight - padding_idx = embed.padding_idx - if padding_idx is None: - padding_idx = -1 - X = torch.nn.functional.embedding( - words, - masked_embed_weight, - padding_idx, - embed.max_norm, - embed.norm_type, - embed.scale_grad_by_freq, - embed.sparse, - ) - return X - - -class LinearDropConnect(nn.Linear): - def __init__(self, in_features, out_features, bias=True, dropout=0.0): - super(LinearDropConnect, self).__init__( - in_features=in_features, out_features=out_features, bias=bias - ) - self.dropout = dropout - - def sample_mask(self): - if self.dropout == 0.0: - self._weight = self.weight - else: - mask = self.weight.new_empty(self.weight.size(), dtype=torch.uint8) - mask.bernoulli_(self.dropout) - self._weight = self.weight.masked_fill(mask, 0.0) - - def forward(self, input, sample_mask=False): - if self.training: - if sample_mask: - self.sample_mask() - return f.linear(input, self._weight, self.bias) - else: - return f.linear(input, self.weight * (1 - self.dropout), self.bias) - - -def cumsoftmax(x, dim=-1): - """ - Cummulative softmax - """ - return torch.cumsum(f.softmax(x, dim=dim), dim=dim) - - -class ONLSTMCell(nn.Module): - """ - ON-LSTM cell part of the ONLSTMStack. - Code credits: https://github.com/yikangshen/Ordered-Neurons - """ - - def __init__(self, input_size, hidden_size, chunk_size, dropconnect=0.0): - super(ONLSTMCell, self).__init__() - self.input_size = input_size - self.hidden_size = hidden_size - self.chunk_size = chunk_size - self.n_chunk = int(hidden_size / chunk_size) - self.ih = nn.Sequential( - nn.Linear(input_size, 4 * hidden_size + self.n_chunk * 2, bias=True) - ) - self.hh = LinearDropConnect( - hidden_size, hidden_size * 4 + self.n_chunk * 2, bias=True, dropout=dropconnect - ) - self.drop_weight_modules = [self.hh] - - def forward(self, input, hidden, transformed_input=None): - hx, cx = hidden - - if transformed_input is None: - transformed_input = self.ih(input) - gates = transformed_input + self.hh(hx) - cingate, cforgetgate = gates[:, : self.n_chunk * 2].chunk(2, 1) - outgate, cell, ingate, forgetgate = ( - gates[:, self.n_chunk * 2 :].view(-1, self.n_chunk * 4, self.chunk_size).chunk(4, 1) - ) - cingate = 1.0 - cumsoftmax(cingate) - cforgetgate = cumsoftmax(cforgetgate) - distance_cforget = 1.0 - cforgetgate.sum(dim=-1) / self.n_chunk - distance_cin = cingate.sum(dim=-1) / self.n_chunk - cingate = cingate[:, :, None] - cforgetgate = cforgetgate[:, :, None] - ingate = f.sigmoid(ingate) - forgetgate = f.sigmoid(forgetgate) - cell = f.tanh(cell) - outgate = f.sigmoid(outgate) - overlap = cforgetgate * cingate - forgetgate = forgetgate * overlap + (cforgetgate - overlap) - ingate = ingate * overlap + (cingate - overlap) - cy = forgetgate * cx + ingate * cell - hy = outgate * f.tanh(cy) - return hy.view(-1, self.hidden_size), cy, (distance_cforget, distance_cin) - - def init_hidden(self, bsz): - weight = next(self.parameters()).data - return ( - weight.new(bsz, self.hidden_size).zero_(), - weight.new(bsz, self.n_chunk, self.chunk_size).zero_(), - ) - - def sample_masks(self): - for m in self.drop_weight_modules: - m.sample_mask() - - -class ONLSTMStack(nn.Module): - """ - ON-LSTM encoder composed of multiple ON-LSTM layers. Each layer is constructed - through ONLSTMCell structures. - Code credits: https://github.com/yikangshen/Ordered-Neurons - """ - - def __init__( - self, - layer_sizes, - chunk_size, - dropout=0.0, - dropconnect=0.0, - embedder=None, - phrase_layer=None, - dropouti=0.5, - dropoutw=0.1, - dropouth=0.3, - batch_size=20, - ): - super(ONLSTMStack, self).__init__() - self.layer_sizes = layer_sizes - self.cells = nn.ModuleList( - [ - ONLSTMCell(layer_sizes[i], layer_sizes[i + 1], chunk_size, dropconnect=dropconnect) - for i in range(len(layer_sizes) - 1) - ] - ) - self.lockdrop = LockedDropout() - self.dropout = dropout - self.dropouti = dropouti - self.dropouth = dropouth - self.sizes = layer_sizes - self.embedder = embedder - dim = self.embedder.token_embedder_words.weight.shape - self.emb = nn.Embedding(dim[0], dim[1]) - self._phrase_layer = phrase_layer - - self.dropoutw = dropoutw - - def get_input_dim(self): - return self.layer_sizes[0] - - def get_output_dim(self): - return self.layer_sizes[-1] - - def init_hidden(self, bsz): - return [c.init_hidden(bsz) for c in self.cells] - - def forward(self, input, task=None): - batch_size = input.size()[1] - hidden = self.init_hidden(batch_size) - return self.forward_actual(input, hidden) - - def forward_actual(self, input, hidden): - abs_inp = input - input = embedded_dropout(self.emb, input, dropout=self.dropoutw if self.training else 0) - input = self.lockdrop(input, self.dropouti) - length, batch_size, _ = input.size() - if self.training: - for c in self.cells: - c.sample_masks() - - prev_state = list(hidden) - prev_layer = input - - raw_outputs = [] - outputs = [] - distances_forget = [] - distances_in = [] - for l in range(len(self.cells)): - curr_layer = [None] * length - dist = [None] * length - t_input = self.cells[l].ih(prev_layer) - for t in range(length): - hidden, cell, d = self.cells[l](None, prev_state[l], transformed_input=t_input[t]) - prev_state[l] = hidden, cell # overwritten every timestep - curr_layer[t] = hidden - dist[t] = d - - prev_layer = torch.stack(curr_layer) - dist_cforget, dist_cin = zip(*dist) - dist_layer_cforget = torch.stack(dist_cforget) - dist_layer_cin = torch.stack(dist_cin) - raw_outputs.append(prev_layer) - if l < len(self.cells) - 1: - prev_layer = self.lockdrop(prev_layer, self.dropouth) - outputs.append(prev_layer) - distances_forget.append(dist_layer_cforget) - distances_in.append(dist_layer_cin) - output = prev_layer - output = self.lockdrop(output, self.dropout) - mask = abs_inp != 0 - self.distances = torch.stack(distances_forget) - return output, mask diff --git a/jiant/modules/onlstm_phrase_layer.py b/jiant/modules/onlstm_phrase_layer.py deleted file mode 100644 index 942f9ed92..000000000 --- a/jiant/modules/onlstm_phrase_layer.py +++ /dev/null @@ -1,46 +0,0 @@ -from allennlp.models.model import Model -from allennlp.nn import InitializerApplicator -from .onlstm.ON_LSTM import ONLSTMStack - - -class ONLSTMPhraseLayer(Model): - """ - Implementation of ON-LSTM (Shen et al., 2019) as a phrase layer for sentence encoder. - ON-LSTM is designed to add syntactic inductive bias to LSTM, - and learns the latent constituency trees jointly with a downstream task. - """ - - def __init__( - self, - vocab, - d_word, - d_hid, - n_layers_enc, - chunk_size, - onlstm_dropconnect, - onlstm_dropouti, - dropout, - onlstm_dropouth, - embedder, - batch_size, - initializer=InitializerApplicator(), - ): - super(ONLSTMPhraseLayer, self).__init__(vocab) - self.onlayer = ONLSTMStack( - [d_word] + [d_hid] * (n_layers_enc - 1) + [d_word], - chunk_size=chunk_size, - dropconnect=onlstm_dropconnect, - dropouti=onlstm_dropouti, - dropout=dropout, - dropouth=onlstm_dropouth, - embedder=embedder, - phrase_layer=None, - batch_size=batch_size, - ) - initializer(self) - - def get_input_dim(self): - return self.onlayer.layer_sizes[0] - - def get_output_dim(self): - return self.onlayer.layer_sizes[-1] diff --git a/jiant/modules/pair_classifier.py b/jiant/modules/pair_classifier.py deleted file mode 100644 index 750259f92..000000000 --- a/jiant/modules/pair_classifier.py +++ /dev/null @@ -1,54 +0,0 @@ -import torch -from torch import nn - - -class PairClassifier(nn.Module): - """ Thin wrapper around a set of modules. - For sentence pair classification. - Pooler specifies how to aggregate inputted sequence of vectors. - Also allows for use of specific token representations to be addded to the overall - representation - """ - - def __init__(self, pooler, classifier, attn=None): - super(PairClassifier, self).__init__() - self.pooler = pooler - self.classifier = classifier - self.attn = attn - - def forward(self, s1, s2, mask1, mask2, idx1=[], idx2=[]): - """ s1, s2: sequences of hidden states corresponding to sentence 1,2 - mask1, mask2: binary mask corresponding to non-pad elements - idx{1,2}: indexes of particular tokens to extract in sentence {1, 2} - and append to the representation, e.g. for WiC - """ - mask1 = mask1.squeeze(-1) if len(mask1.size()) > 2 else mask1 - mask2 = mask2.squeeze(-1) if len(mask2.size()) > 2 else mask2 - if self.attn is not None: - s1, s2 = self.attn(s1, s2, mask1, mask2) - emb1 = self.pooler(s1, mask1) - emb2 = self.pooler(s2, mask2) - - s1_ctx_embs = [] - for idx in [i.long() for i in idx1]: - if len(idx.shape) == 1: - idx = idx.unsqueeze(-1) - if len(idx.shape) == 2: - idx = idx.unsqueeze(-1).expand([-1, -1, s1.size(-1)]) - s1_ctx_emb = s1.gather(dim=1, index=idx) - s1_ctx_embs.append(s1_ctx_emb.squeeze(dim=1)) - emb1 = torch.cat([emb1] + s1_ctx_embs, dim=-1) - - s2_ctx_embs = [] - for idx in [i.long() for i in idx2]: - if len(idx.shape) == 1: - idx = idx.unsqueeze(-1) - if len(idx.shape) == 2: - idx = idx.unsqueeze(-1).expand([-1, -1, s2.size(-1)]) - s2_ctx_emb = s2.gather(dim=1, index=idx) - s2_ctx_embs.append(s2_ctx_emb.squeeze(dim=1)) - emb2 = torch.cat([emb2] + s2_ctx_embs, dim=-1) - - pair_emb = torch.cat([emb1, emb2, torch.abs(emb1 - emb2), emb1 * emb2], 1) - logits = self.classifier(pair_emb) - return logits diff --git a/jiant/modules/prpn/LSTMCell.py b/jiant/modules/prpn/LSTMCell.py deleted file mode 100644 index e7444f1d3..000000000 --- a/jiant/modules/prpn/LSTMCell.py +++ /dev/null @@ -1,54 +0,0 @@ -""" -LSTMCell used in the Reading Network of PRPN -Reference: Parsing-Reading-Predict Networks (PRPN; Shen et al., 2018) -All the modules in this file are taken without change from: https://github.com/yikangshen/PRPN -""" -import torch.nn as nn -import torch.nn.functional as F -from torch.nn.modules.rnn import * - - -class LayerNorm(nn.Module): - def __init__(self, features, eps=1e-6): - super(LayerNorm, self).__init__() - self.gamma = nn.Parameter(torch.ones(features)) - self.beta = nn.Parameter(torch.zeros(features)) - self.eps = eps - - def forward(self, x): - mean = x.mean(-1, keepdim=True) - std = x.std(-1, keepdim=True) - return self.gamma * (x - mean) / (std + self.eps) + self.beta - - -class LSTMCell(RNNCellBase): - def __init__(self, input_size, hidden_size, bias=True, dropout=0): - super(LSTMCell, self).__init__(input_size, hidden_size, bias, num_chunks=4) - self.input_size = input_size - self.hidden_size = hidden_size - self.bias = bias - self.ih = nn.Sequential( - nn.Linear(input_size, 4 * hidden_size, bias), LayerNorm(4 * hidden_size) - ) - self.hh = nn.Sequential( - nn.Linear(hidden_size, 4 * hidden_size, bias), LayerNorm(4 * hidden_size) - ) - self.c_norm = LayerNorm(hidden_size) - self.drop = nn.Dropout(dropout) - - def forward(self, input, hidden): - - hx, cx = hidden - gates = self.ih(input) + self.hh(hx) - - ingate, forgetgate, cellgate, outgate = gates.chunk(4, 1) - - ingate = F.sigmoid(ingate) - forgetgate = F.sigmoid(forgetgate) - cellgate = F.tanh(cellgate) - outgate = F.sigmoid(outgate) - - cy = forgetgate * cx + ingate * cellgate - hy = outgate * F.tanh(self.c_norm(cy)) - - return hy, cy diff --git a/jiant/modules/prpn/PRPN.py b/jiant/modules/prpn/PRPN.py deleted file mode 100644 index d3f4c7cc0..000000000 --- a/jiant/modules/prpn/PRPN.py +++ /dev/null @@ -1,160 +0,0 @@ -""" -Code for Parsing-Reading-Predict Networks (PRPN; Shen et al., 2018) -This file is a version of a class from https://github.com/yikangshen/PRPN, modified to integrate with jiant. -We modified the forward function of original PRPN code. -""" -import torch -import torch.nn as nn - -from .ParsingNetwork import ParsingNetwork -from .PredictNetwork import PredictNetwork -from .ReadingNetwork import ReadingNetwork - - -class PRPN(nn.Module): - """Container module with an encoder, a recurrent module, and a decoder.""" - - def __init__( - self, - ninp, - nhid, - nlayers, - nslots=15, - nlookback=5, - resolution=0.1, - embedder=None, - dropout=0.7, - idropout=0.5, - rdropout=0.5, - phrase_layer=None, - tie_weights=True, - hard=True, - res=0, - batch_size=20, - ): - super(PRPN, self).__init__() - - self.nhid = nhid - self.ninp = ninp - self.nlayers = nlayers - self.nslots = nslots - self.nlookback = nlookback - - self.drop = nn.Dropout(dropout) - self.idrop = nn.Dropout(idropout) - self.rdrop = nn.Dropout(rdropout) - - # Feedforward layers - - self.embedder = embedder - dim = self.embedder.token_embedder_words.weight.shape - - self._phrase_layer = phrase_layer - - self.ninp = ninp - self.emb = nn.Embedding(dim[0], self.ninp) - self.parser = ParsingNetwork(self.ninp, nhid, nslots, nlookback, resolution, idropout, hard) - self.reader = nn.ModuleList( - [ReadingNetwork(self.ninp, nhid, nslots, dropout=dropout, idropout=idropout)] - + [ - ReadingNetwork(nhid, nhid, nslots, dropout=idropout, idropout=idropout) - for i in range(nlayers - 1) - ] - ) - self.predictor = PredictNetwork(nhid, self.ninp, nslots, idropout, res) - # self.decoder = nn.Linear(ninp, ntoken) - - # if tie_weights: - # self.decoder.weight = self.encoder.weight - - self.attentions = None - self.gates = None - - self.init_weights() - - def get_input_dim(self): - return self.ninp - - def get_output_dim(self): - return self.ninp - - def init_weights(self): - initrange = 0.01 - self.emb.weight.data.uniform_(-initrange, initrange) - # self.decoder.bias.data.fill_(0) - # self.decoder.weight.data.uniform_(-initrange, initrange) - - def clip_grad_norm(self, clip): - for model in self.reader: - torch.nn.utils.clip_grad_norm(model.memory_rnn.parameters(), clip) - - def forward(self, input, task=None): - batch_size = input.size()[1] - hidden = self.init_hidden(batch_size) - return self.forward_actual(input, hidden) - - def forward_actual(self, input, hidden_states): - abs_inp = input - ntimestep = input.size(0) - bsz = input.size(1) - emb = self.emb(input) # timesteps, bsz, ninp - output_h = [] - output_memory = [] - attentions = [] - - reader_state, parser_state, predictor_state = hidden_states # memory_h: bsz, nslots, nhid - - (memory_gate, memory_gate_next), gate, parser_state = self.parser(emb, parser_state) - - rmask = torch.autograd.Variable(torch.ones(self.nlayers, self.nhid)) - if input.is_cuda: - rmask = rmask.cuda() - rmask = self.rdrop(rmask) - - for i in range(input.size(0)): - emb_i = emb[i] # emb_i: bsz, nhid - attention = [] - attention.append(memory_gate[i]) - - # summarize layer - h_i = emb_i - for j in range(self.nlayers): - hidden = reader_state[j] - - h_i, new_memory, attention0 = self.reader[j](h_i, hidden, memory_gate[i], rmask[j]) - - # updata states - attention.append(attention0) - reader_state[j] = new_memory - - # predict layer - selected_memory_h, predictor_state, attention1 = self.predictor.attention( - h_i, predictor_state, gate_time=memory_gate_next[i] - ) - output_h.append(h_i) - output_memory.append(selected_memory_h) - - attention.append(memory_gate_next[i]) - attention.append(attention1) - attentions.append(torch.stack(attention, dim=1)) - - self.attentions = torch.stack(attentions, dim=0) - self.gates = gate - - output_h = torch.stack(output_h, dim=0) - output_memory = torch.stack(output_memory, dim=0) - output = self.predictor(output_h.view(-1, self.nhid), output_memory.view(-1, self.nhid)) - - output = self.drop(output).view(ntimestep, bsz, -1) - # decoded = self.decoder(output) - # return decoded.view(ntimestep, bsz, -1), (reader_state, parser_state, predictor_state) - mask = abs_inp != 0 - - return output, mask - - def init_hidden(self, bsz): - return ( - [self.reader[i].init_hidden(bsz) for i in range(self.nlayers)], - self.parser.init_hidden(bsz), - self.predictor.init_hidden(bsz), - ) diff --git a/jiant/modules/prpn/ParsingNetwork.py b/jiant/modules/prpn/ParsingNetwork.py deleted file mode 100644 index 51bbdf7a7..000000000 --- a/jiant/modules/prpn/ParsingNetwork.py +++ /dev/null @@ -1,86 +0,0 @@ -""" -Parsing Network (convolutional parser) of PRPN -Reference: Parsing-Reading-Predict Networks (PRPN; Shen et al., 2018) -All the modules in this file are taken without change from: https://github.com/yikangshen/PRPN -""" -import numpy -import torch -import torch.nn as nn -import torch.nn.functional as F -from torch.autograd import Variable - - -class ParsingNetwork(nn.Module): - def __init__(self, ninp, nhid, nslots=5, nlookback=1, resolution=0.1, dropout=0.4, hard=False): - super(ParsingNetwork, self).__init__() - - self.nhid = nhid - self.ninp = ninp - self.nslots = nslots - self.nlookback = nlookback - self.resolution = resolution - self.hard = hard - - self.drop = nn.Dropout(dropout) - - # Attention layers - self.gate = nn.Sequential( - nn.Dropout(dropout), - nn.Conv1d(ninp, nhid, (nlookback + 1)), - nn.BatchNorm1d(nhid), - nn.ReLU(), - nn.Dropout(dropout), - nn.Conv1d(nhid, 2, 1, groups=2), - nn.Sigmoid(), - ) - - def forward(self, emb, parser_state): - emb_last, cum_gate = parser_state - ntimestep = emb.size(0) - - emb_last = torch.cat([emb_last, emb], dim=0) - emb = emb_last.transpose(0, 1).transpose(1, 2) # bsz, ninp, ntimestep + nlookback - - gates = self.gate(emb) # bsz, 2, ntimestep - gate = gates[:, 0, :] - gate_next = gates[:, 1, :] - cum_gate = torch.cat([cum_gate, gate], dim=1) - gate_hat = torch.stack( - [cum_gate[:, i : i + ntimestep] for i in range(self.nslots, 0, -1)], dim=2 - ) # bsz, ntimestep, nslots - - if self.hard: - memory_gate = ( - F.hardtanh((gate[:, :, None] - gate_hat) / self.resolution * 2 + 1) + 1 - ) / 2 - else: - memory_gate = F.sigmoid( - (gate[:, :, None] - gate_hat) / self.resolution * 10 + 5 - ) # bsz, ntimestep, nslots - memory_gate = torch.cumprod(memory_gate, dim=2) # bsz, ntimestep, nlookback+1 - memory_gate = torch.unbind(memory_gate, dim=1) - - if self.hard: - memory_gate_next = ( - F.hardtanh((gate_next[:, :, None] - gate_hat) / self.resolution * 2 + 1) + 1 - ) / 2 - else: - memory_gate_next = F.sigmoid( - (gate_next[:, :, None] - gate_hat) / self.resolution * 10 + 5 - ) # bsz, ntimestep, nslots - memory_gate_next = torch.cumprod(memory_gate_next, dim=2) # bsz, ntimestep, nlookback+1 - memory_gate_next = torch.unbind(memory_gate_next, dim=1) - - return ( - (memory_gate, memory_gate_next), - gate, - (emb_last[-self.nlookback :], cum_gate[:, -self.nslots :]), - ) - - def init_hidden(self, bsz): - weight = next(self.parameters()).data - self.ones = Variable(weight.new(bsz, 1).zero_() + 1) - return ( - Variable(weight.new(self.nlookback, bsz, self.ninp).zero_()), - Variable(weight.new(bsz, self.nslots).zero_() + numpy.inf), - ) diff --git a/jiant/modules/prpn/PredictNetwork.py b/jiant/modules/prpn/PredictNetwork.py deleted file mode 100644 index cb008a924..000000000 --- a/jiant/modules/prpn/PredictNetwork.py +++ /dev/null @@ -1,59 +0,0 @@ -""" -Prediction Network of PRPN, that predicts the language model probabilities -Reference: Parsing-Reading-Predict Networks (PRPN; Shen et al., 2018) -All the modules in this file are taken without change from: https://github.com/yikangshen/PRPN -""" -import math - -import torch -import torch.nn as nn -from torch.autograd import Variable - -from .blocks import ResBlock, softmax - - -class PredictNetwork(nn.Module): - def __init__(self, ninp, nout, nslots, dropout, nlayers=1): - super(PredictNetwork, self).__init__() - - self.ninp = ninp - self.nout = nout - self.nslots = nslots - self.nlayers = nlayers - - self.drop = nn.Dropout(dropout) - - self.projector_pred = nn.Sequential( - nn.Dropout(dropout), nn.Linear(ninp, ninp), nn.Dropout(dropout) - ) - - if nlayers > 0: - self.res = ResBlock(ninp * 2, nout, dropout, nlayers) - else: - self.res = None - - self.ffd = nn.Sequential( - nn.Dropout(dropout), nn.Linear(ninp * 2, nout), nn.BatchNorm1d(nout), nn.Tanh() - ) - - def forward(self, input, input_memory): - input = torch.cat([input, input_memory], dim=1) - if self.nlayers > 0: - input = self.res(input) - output = self.ffd(input) - return output - - def attention(self, input, memory, gate_time): - key = self.projector_pred(input) - # select memory to use - logits = torch.bmm(memory, key[:, :, None]).squeeze(2) - logits = logits / math.sqrt(self.ninp) - attention = softmax(logits, gate_time) - selected_memory_h = (memory * attention[:, :, None]).sum(dim=1) - memory = torch.cat([input[:, None, :], memory[:, :-1, :]], dim=1) - return selected_memory_h, memory, attention - - def init_hidden(self, bsz): - weight = next(self.parameters()).data - self.ones = Variable(weight.new(bsz, 1).zero_() + 1.0) - return Variable(weight.new(bsz, self.nslots, self.ninp).zero_()) diff --git a/jiant/modules/prpn/ReadingNetwork.py b/jiant/modules/prpn/ReadingNetwork.py deleted file mode 100644 index 8ca7b3a95..000000000 --- a/jiant/modules/prpn/ReadingNetwork.py +++ /dev/null @@ -1,62 +0,0 @@ -""" -Reading Network (LSTMN with self-attention) of PRPN -Reference: Parsing-Reading-Predict Networks (PRPN; Shen et al., 2018) -All the modules in this file are taken without change from: https://github.com/yikangshen/PRPN -""" -import math - -import torch -import torch.nn as nn -from torch.autograd import Variable - -from .blocks import softmax -from .LSTMCell import LSTMCell - - -class ReadingNetwork(nn.Module): - def __init__(self, ninp, nout, nslots, dropout, idropout): - super(ReadingNetwork, self).__init__() - - self.ninp = ninp - self.nout = nout - self.nslots = nslots - self.drop = nn.Dropout(dropout) - self.memory_rnn = LSTMCell(ninp, nout, bias=True, dropout=0) - self.projector_summ = nn.Sequential( - nn.Dropout(idropout), nn.Linear(ninp + nout, nout), nn.Dropout(idropout) - ) - - def forward(self, input, memory, gate_time, rmask): - memory_h, memory_c = memory - - # attention - selected_memory_h, selected_memory_c, attention0 = self.attention( - input, memory_h, memory_c, gate=gate_time - ) - - # recurrent - input = self.drop(input) - h_i, c_i = self.memory_rnn(input, (selected_memory_h * rmask, selected_memory_c)) - - # updata memory - memory_h = torch.cat([h_i[:, None, :], memory_h[:, :-1, :]], dim=1) - memory_c = torch.cat([c_i[:, None, :], memory_c[:, :-1, :]], dim=1) - - return h_i, (memory_h, memory_c), attention0 - - def attention(self, input, memory_h, memory_c, gate=None): - # select memory to use - key = self.projector_summ(torch.cat([input, memory_h[:, 0, :]], dim=1)) - logits = torch.bmm(memory_h, key[:, :, None]).squeeze(2) - logits = logits / math.sqrt(self.nout) - attention = softmax(logits, gate) - selected_memory_h = (memory_h * attention[:, :, None]).sum(dim=1) - selected_memory_c = (memory_c * attention[:, :, None]).sum(dim=1) - return selected_memory_h, selected_memory_c, attention - - def init_hidden(self, bsz): - weight = next(self.parameters()).data - return ( - Variable(weight.new(bsz, self.nslots, self.nout).zero_()), - Variable(weight.new(bsz, self.nslots, self.nout).zero_()), - ) diff --git a/jiant/modules/prpn/blocks.py b/jiant/modules/prpn/blocks.py deleted file mode 100644 index 6c58a2c0b..000000000 --- a/jiant/modules/prpn/blocks.py +++ /dev/null @@ -1,62 +0,0 @@ -""" -ResNet block and masked-softmax used in PRPN -Reference: Parsing-Reading-Predict Networks (PRPN; Shen et al., 2018) -All the modules in this file are taken without change from: https://github.com/yikangshen/PRPN -""" -import torch -import torch.nn as nn -import torch.nn.functional as F - - -def stick_breaking(logits): - e = F.sigmoid(logits) - z = (1 - e).cumprod(dim=1) - p = torch.cat([e.narrow(1, 0, 1), e[:, 1:] * z[:, :-1]], dim=1) - - return p - - -def softmax(x, mask=None): - """ - softmax function with masking for self-attention - """ - max_x, _ = x.max(dim=-1, keepdim=True) - e_x = torch.exp(x - max_x) - if not (mask is None): - e_x = e_x * mask - out = e_x / (e_x.sum(dim=-1, keepdim=True) + 1e-8) - - return out - - -class ResBlock(nn.Module): - """ - Resnet block used in parsing network of PRPN - """ - - def __init__(self, ninp, nout, dropout, nlayers=1): - super(ResBlock, self).__init__() - - self.nlayers = nlayers - - self.drop = nn.Dropout(dropout) - - self.res = nn.ModuleList( - [ - nn.Sequential( - nn.Linear(ninp, ninp), - nn.BatchNorm1d(ninp), - nn.ReLU(), - nn.Dropout(dropout), - nn.Linear(ninp, ninp), - nn.BatchNorm1d(ninp), - ) - for _ in range(nlayers) - ] - ) - - def forward(self, input): - # input = self.drop(input) - for i in range(self.nlayers): - input = F.relu(self.res[i](input) + input) - return input diff --git a/jiant/modules/prpn_phrase_layer.py b/jiant/modules/prpn_phrase_layer.py deleted file mode 100644 index a024ee845..000000000 --- a/jiant/modules/prpn_phrase_layer.py +++ /dev/null @@ -1,53 +0,0 @@ -from allennlp.models.model import Model -from allennlp.nn import InitializerApplicator -from .prpn.PRPN import PRPN - - -class PRPNPhraseLayer(Model): - """ - Implementation of PRPN (Shen et al., 2018) as a phrase layer for sentence encoder. - PRPN has a parser component that learns the latent constituency trees jointly with a - downstream task. - """ - - def __init__( - self, - vocab, - d_word, - d_hid, - n_layers_enc, - n_slots, - n_lookback, - resolution, - dropout, - idropout, - rdropout, - res, - embedder, - batch_size, - initializer=InitializerApplicator(), - ): - super(PRPNPhraseLayer, self).__init__(vocab) - - self.prpnlayer = PRPN( - ninp=d_word, - nhid=d_hid, - nlayers=n_layers_enc, - nslots=n_slots, - nlookback=n_lookback, - resolution=resolution, - dropout=dropout, - idropout=idropout, - rdropout=rdropout, - res=res, - batch_size=batch_size, - embedder=embedder, - phrase_layer=None, - ) - initializer(self) - - def get_input_dim(self): - return self.prpnlayer.ninp - - def get_output_dim(self): - return self.prpnlayer.ninp diff --git a/jiant/modules/sentence_encoder.py b/jiant/modules/sentence_encoder.py deleted file mode 100644 index e8d99d0e7..000000000 --- a/jiant/modules/sentence_encoder.py +++ /dev/null @@ -1,183 +0,0 @@ -""" Different model components to use in building the overall model. - -The main component of interest is SentenceEncoder, which all the models use. """ - -import torch -import torch.utils.data -import torch.utils.data.distributed -from allennlp.models.model import Model - -# StackedSelfAttentionEncoder -from allennlp.nn import InitializerApplicator, util -from allennlp.modules import Highway, TimeDistributed - -from jiant.tasks.tasks import PairClassificationTask, PairRegressionTask -from jiant.utils import utils -from jiant.modules.simple_modules import NullPhraseLayer -from jiant.modules.bilm_encoder import BiLMEncoder -from jiant.modules.onlstm.ON_LSTM import ONLSTMStack -from jiant.modules.prpn.PRPN import PRPN - - -class SentenceEncoder(Model): - """ Given a sequence of tokens, embed each token and pass through a sequence encoder. """ - - # NOTE: Do not apply dropout to the input of this module. Will be applied - # internally. - - def __init__( - self, - vocab, - text_field_embedder, - num_highway_layers, - phrase_layer, - skip_embs=True, - cove_layer=None, - dropout=0.2, - mask_lstms=True, - sep_embs_for_skip=False, - initializer=InitializerApplicator(), - ): - super(SentenceEncoder, self).__init__(vocab) - - if text_field_embedder is None: - self._text_field_embedder = lambda x: x - d_emb = 0 - self._highway_layer = lambda x: x - else: - self._text_field_embedder = text_field_embedder - d_emb = text_field_embedder.get_output_dim() - self._highway_layer = TimeDistributed(Highway(d_emb, num_highway_layers)) - - self._phrase_layer = phrase_layer - self._cove_layer = cove_layer - self.pad_idx = vocab.get_token_index(vocab._padding_token) - self.skip_embs = skip_embs - self.sep_embs_for_skip = sep_embs_for_skip - d_inp_phrase = self._phrase_layer.get_input_dim() - self.output_dim = phrase_layer.get_output_dim() + (skip_embs * d_inp_phrase) - - if dropout > 0: - self._dropout = torch.nn.Dropout(p=dropout) - else: - self._dropout = lambda x: x - self._mask_lstms = mask_lstms - - initializer(self) - - def forward(self, sent, task, reset=True): - # pylint: disable=arguments-differ - """ - Args: - - sent (Dict[str, torch.LongTensor]): From a ``TextField``. - - task (Task): Used by the _text_field_embedder to pick the correct output - ELMo representation. - - reset (Bool): if True, manually reset the states of the ELMo LSTMs present - (if using BiLM or ELMo embeddings). Set False, if want to preserve statefulness. - Returns: - - sent_enc (torch.FloatTensor): (b_size, seq_len, d_emb) - the padded values in sent_enc are set to 0 - - sent_mask (torch.FloatTensor): (b_size, seq_len, d_emb); all 0/1s - """ - if reset: - self.reset_states() - - # General sentence embeddings (for sentence encoder). - # Make sent_mask first, transformers text_field_embedder will change the token index - sent_mask = util.get_text_field_mask(sent).float() - # Skip this for probing runs that don't need it. - if not isinstance(self._phrase_layer, NullPhraseLayer): - word_embs_in_context = self._highway_layer(self._text_field_embedder(sent)) - else: - word_embs_in_context = None - - # Task-specific sentence embeddings (e.g. custom ELMo weights). - # Skip computing this if it won't be used. - if self.sep_embs_for_skip: - task_word_embs_in_context = self._highway_layer( - self._text_field_embedder(sent, task._classifier_name) - ) - else: - task_word_embs_in_context = None - - # Make sure we're embedding /something/ - assert (word_embs_in_context is not None) or (task_word_embs_in_context is not None) - - if self._cove_layer is not None: - # Slightly wasteful as this repeats the GloVe lookup internally, - # but this allows CoVe to be used alongside other embedding models - # if we want to. - sent_lens = torch.ne(sent["words"], self.pad_idx).long().sum(dim=-1).data - # CoVe doesn't use or , so strip these before running. - # Note that we need to also drop the last column so that CoVe returns - # the right shape. If all inputs have then this will be the - # only thing clipped. - sent_cove_embs_raw = self._cove_layer(sent["words"][:, 1:-1], sent_lens - 2) - pad_col = torch.zeros( - sent_cove_embs_raw.size()[0], - 1, - sent_cove_embs_raw.size()[2], - dtype=sent_cove_embs_raw.dtype, - device=sent_cove_embs_raw.device, - ) - sent_cove_embs = torch.cat([pad_col, sent_cove_embs_raw, pad_col], dim=1) - if word_embs_in_context is not None: - word_embs_in_context = torch.cat([word_embs_in_context, sent_cove_embs], dim=-1) - if task_word_embs_in_context is not None: - task_word_embs_in_context = torch.cat( - [task_word_embs_in_context, sent_cove_embs], dim=-1 - ) - - if word_embs_in_context is not None: - word_embs_in_context = self._dropout(word_embs_in_context) - if task_word_embs_in_context is not None: - task_word_embs_in_context = self._dropout(task_word_embs_in_context) - - # The rest of the model - sent_lstm_mask = sent_mask if self._mask_lstms else None - if word_embs_in_context is not None: - if isinstance(self._phrase_layer, ONLSTMStack) or isinstance(self._phrase_layer, PRPN): - # The ONLSTMStack or PRPN takes the raw words as input and computes - # embeddings separately. - sent_enc, _ = self._phrase_layer( - torch.transpose(sent["words"], 0, 1), sent_lstm_mask - ) - sent_enc = torch.transpose(sent_enc, 0, 1) - else: - sent_enc = self._phrase_layer(word_embs_in_context, sent_lstm_mask) - else: - sent_enc = None - - # ELMoLSTM returns all layers, we just want to use the top layer - sent_enc = sent_enc[-1] if isinstance(self._phrase_layer, BiLMEncoder) else sent_enc - sent_enc = self._dropout(sent_enc) if sent_enc is not None else sent_enc - if self.skip_embs: - # Use skip connection with original sentence embs or task sentence - # embs - skip_vec = task_word_embs_in_context if self.sep_embs_for_skip else word_embs_in_context - utils.assert_for_log( - skip_vec is not None, - "skip_vec is none - perhaps embeddings are not configured properly?", - ) - if isinstance(self._phrase_layer, NullPhraseLayer): - sent_enc = skip_vec - else: - sent_enc = torch.cat([sent_enc, skip_vec], dim=-1) - - sent_mask = sent_mask.unsqueeze(dim=-1) - pad_mask = sent_mask == 0 - - assert sent_enc is not None - sent_enc = sent_enc.masked_fill(pad_mask, 0) - return sent_enc, sent_mask - - def reset_states(self): - """ Reset ELMo if present; reset BiLM (ELMoLSTM) states if present """ - if "token_embedder_elmo" in [ - name for name, _ in self._text_field_embedder.named_children() - ] and "_elmo" in [ - name for name, _ in self._text_field_embedder.token_embedder_elmo.named_children() - ]: - self._text_field_embedder.token_embedder_elmo._elmo._elmo_lstm._elmo_lstm.reset_states() # noqa # eek. - if isinstance(self._phrase_layer, BiLMEncoder): - self._phrase_layer.reset_states() diff --git a/jiant/modules/seq2seq_decoder.py b/jiant/modules/seq2seq_decoder.py deleted file mode 100644 index 7791625f5..000000000 --- a/jiant/modules/seq2seq_decoder.py +++ /dev/null @@ -1,359 +0,0 @@ -# This is a slightly modified version of the AllenNLP SimpleSeq2Seq class: -# https://github.com/allenai/allennlp/blob/master/allennlp/models/encoder_decoders/simple_seq2seq.py # noqa - -import logging as log -from typing import Dict, Tuple - -import torch -from allennlp.common.util import END_SYMBOL, START_SYMBOL -from allennlp.data.vocabulary import Vocabulary -from allennlp.models.model import Model -from allennlp.modules.attention import BilinearAttention -from allennlp.modules.token_embedders import Embedding -from allennlp.nn.beam_search import BeamSearch -from allennlp.nn.util import get_text_field_mask, sequence_cross_entropy_with_logits, weighted_sum -from overrides import overrides -from torch.nn.functional import log_softmax -from torch.nn.modules.linear import Linear -from torch.nn.modules.rnn import LSTMCell - -from jiant.modules.simple_modules import Pooler -from jiant.modules.attention import BahdanauAttention -from jiant.preprocess import SOS_TOK, EOS_TOK, UNK_TOK - - -class Seq2SeqDecoder(Model): - """ - This is a slightly modified version of AllenNLP SimpleSeq2Seq class - """ - - def __init__( - self, - vocab: Vocabulary, - input_dim: int, - decoder_hidden_size: int, - max_decoding_steps: int, - output_proj_input_dim: int, - target_namespace: str = "targets", - target_embedding_dim: int = None, - attention: str = "none", - dropout: float = 0.0, - scheduled_sampling_ratio: float = 0.0, - beam_size=10, - ) -> None: - super(Seq2SeqDecoder, self).__init__(vocab) - - self._max_decoding_steps = max_decoding_steps - self._target_namespace = target_namespace - - # We need the start symbol to provide as the input at the first timestep of decoding, and - # end symbol as a way to indicate the end of the decoded sequence. - self._start_index = self.vocab.get_token_index(SOS_TOK, self._target_namespace) - self._end_index = self.vocab.get_token_index(EOS_TOK, self._target_namespace) - self._unk_index = self.vocab.get_token_index(UNK_TOK, self._target_namespace) - num_classes = self.vocab.get_vocab_size(self._target_namespace) - - # Decoder output dim needs to be the same as the encoder output dim since we initialize the - # hidden state of the decoder with that of the final hidden states of the encoder. Also, if - # we're using attention with ``DotProductSimilarity``, this is needed. - self._encoder_output_dim = input_dim - self._decoder_hidden_dim = decoder_hidden_size - if self._encoder_output_dim != self._decoder_hidden_dim: - self._projection_encoder_out = Linear( - self._encoder_output_dim, self._decoder_hidden_dim - ) - else: - self._projection_encoder_out = lambda x: x - self._decoder_output_dim = self._decoder_hidden_dim - self._output_proj_input_dim = output_proj_input_dim - self._target_embedding_dim = target_embedding_dim - self._target_embedder = Embedding(num_classes, self._target_embedding_dim) - - # Used to get an initial hidden state from the encoder states - self._sent_pooler = Pooler(project=True, d_inp=input_dim, d_proj=decoder_hidden_size) - - if attention == "Bahdanau": - self._decoder_attention = BahdanauAttention( - decoder_hidden_size + target_embedding_dim, input_dim - ) - # The output of attention, a weighted average over encoder outputs, will be - # concatenated to the input vector of the decoder at each time - # step. - self._decoder_input_dim = input_dim + target_embedding_dim - elif attention == "bilinear": - self._decoder_attention = BilinearAttention( - decoder_hidden_size + target_embedding_dim, input_dim - ) - # The output of attention, a weighted average over encoder outputs, will be - # concatenated to the input vector of the decoder at each time - # step. - self._decoder_input_dim = input_dim + target_embedding_dim - elif attention == "none": - self._decoder_attention = None - self._decoder_input_dim = target_embedding_dim - else: - raise Exception("attention not implemented {}".format(attention)) - - self._decoder_cell = LSTMCell(self._decoder_input_dim, self._decoder_hidden_dim) - # Allow for a bottleneck layer between encoder outputs and distribution over vocab - # The bottleneck layer consists of a linear transform and helps to reduce - # number of parameters - if self._output_proj_input_dim != self._decoder_output_dim: - self._projection_bottleneck = Linear( - self._decoder_output_dim, self._output_proj_input_dim - ) - else: - self._projection_bottleneck = lambda x: x - self._output_projection_layer = Linear(self._output_proj_input_dim, num_classes) - self._dropout = torch.nn.Dropout(p=dropout) - - # At prediction time, we'll use a beam search to find the best target sequence. - self.beam_size = beam_size - self._beam_search = BeamSearch(self._end_index, max_steps=max_decoding_steps, beam_size=1) - - def _initalize_hidden_context_states(self, encoder_outputs, encoder_outputs_mask): - """ - Initialization of the decoder state, based on the encoder output. - Parameters - ---------- - encoder_outputs: torch.FloatTensor, [bs, T, h] - encoder_outputs_mask: torch.LongTensor, [bs, T, 1] - """ - - if self._decoder_attention is not None: - encoder_outputs = self._projection_encoder_out(encoder_outputs) - encoder_outputs.data.masked_fill_(1 - encoder_outputs_mask.byte().data, -float("inf")) - - decoder_hidden = encoder_outputs.new_zeros( - encoder_outputs_mask.size(0), self._decoder_hidden_dim - ) - decoder_context = encoder_outputs.max(dim=1)[0] - else: - decoder_hidden = self._sent_pooler(encoder_outputs, encoder_outputs_mask) - decoder_context = encoder_outputs.new_zeros( - encoder_outputs_mask.size(0), self._decoder_hidden_dim - ) - - return decoder_hidden, decoder_context - - def take_step( - self, last_predictions: torch.Tensor, state: Dict[str, torch.Tensor] - ) -> Tuple[torch.Tensor, Dict[str, torch.Tensor]]: - """Take a decoding step. This is called by the beam search class.""" - - decoder_input = self._prepare_decode_step_input( - last_predictions, - state["decoder_hidden"], - state["encoder_outputs"], - state["encoder_outputs_mask"], - ) - state["decoder_hidden"], state["decoder_context"] = self._decoder_cell( - decoder_input, (state["decoder_hidden"], state["decoder_context"]) - ) - - # output projection - proj_input = self._projection_bottleneck(state["decoder_hidden"]) - # (batch_size, num_classes) - step_logit = self._output_projection_layer(proj_input) - - log_probs = log_softmax(step_logit) - - return log_probs, state - - def _forward_beam_search(self, state: Dict[str, torch.Tensor]) -> Dict[str, torch.Tensor]: - """Make forward pass during prediction using a beam search.""" - batch_size = state["encoder_outputs_mask"].size()[0] - start_predictions = state["encoder_outputs_mask"].new_full( - (batch_size,), fill_value=self._start_index - ) - - # shape (all_top_k_predictions): (batch_size, beam_size, num_decoding_steps) - # shape (log_probabilities): (batch_size, beam_size) - all_top_k_predictions, log_probabilities = self._beam_search.search( - start_predictions, state, self.take_step - ) - - output_dict = {"log_probabilities": log_probabilities, "predictions": all_top_k_predictions} - return output_dict - - @overrides - def forward( - self, # type: ignore - encoder_outputs, # type: ignore - encoder_outputs_mask, # type: ignore - target_tokens: Dict[str, torch.LongTensor] = None, - generate=False, - ) -> Dict[str, torch.Tensor]: - # pylint: disable=arguments-differ - """ - Forward pass for the decoder. - - 1) Training/validation/test with gold data [if generate is False]: - loss is computed given the gold target tokens; - accuracy/BLEU/etc. are computied using predicted tokens, NO beam search - 2) Generation [if generate is True]: - loss is NOT computed (the returned loss is 0.0) if no target is given, - otherwise as above - accuracy/BLEU/etc. are computed using predicted tokens, beam search is used - - Parameters - ---------- - encoder_outputs : torch.FloatTensor, [bs, T, h] - encoder_outputs_mask : torch.LongTensor, [bs, T, 1] - target_tokens : Dict[str, torch.LongTensor] - generate: bool; if True, use beam search - """ - batch_size, _, _ = encoder_outputs.size() - - num_decoding_steps = ( - target_tokens["words"].size()[1] - 1 - if target_tokens is not None - else self._max_decoding_steps - ) - - decoder_hidden, decoder_context = self._initalize_hidden_context_states( - encoder_outputs, encoder_outputs_mask - ) - - # First, generate output without teacher forcing (for certain metrics like BLEU). - # State for beam search - state = { - "encoder_outputs_mask": encoder_outputs_mask, - "encoder_outputs": encoder_outputs, - "decoder_hidden": decoder_hidden, - "decoder_context": decoder_context, - } - if generate: - self._beam_search.beam_size = self.beam_size - beam_search_output = self._forward_beam_search(state) - if not target_tokens: # No gold target sequence available - return beam_search_output - - # The following is only computed if a gold target sequence is given. - step_logits = [] - targets = target_tokens["words"] - - for timestep in range(num_decoding_steps): - input_choices = targets[:, timestep] - decoder_input = self._prepare_decode_step_input( - input_choices, decoder_hidden, encoder_outputs, encoder_outputs_mask - ) - decoder_hidden, decoder_context = self._decoder_cell( - decoder_input, (decoder_hidden, decoder_context) - ) - - # output projection - proj_input = self._projection_bottleneck(decoder_hidden) - # (batch_size, num_classes) - output_projections = self._output_projection_layer(proj_input) - - # list of (batch_size, 1, num_classes) - step_logit = output_projections.unsqueeze(1) - step_logits.append(step_logit) - - # (batch_size, num_decoding_steps, num_classes) - logits = torch.cat(step_logits, 1) - output_dict = {"logits": logits} - - target_mask = get_text_field_mask(target_tokens) - output_dict["target_mask"] = target_mask - relevant_logits = logits[:, : targets.shape[1] - 1, :].contiguous() - loss = self._get_loss(relevant_logits, targets, target_mask) - output_dict["loss"] = loss - - output_dict["predictions"] = beam_search_output["predictions"] - output_dict["log_probabilities"] = beam_search_output["log_probabilities"] - - return output_dict - - def _prepare_decode_step_input( - self, - input_indices: torch.LongTensor, - decoder_hidden_state: torch.LongTensor = None, - encoder_outputs: torch.LongTensor = None, - encoder_outputs_mask: torch.LongTensor = None, - ) -> torch.LongTensor: - """ - Given the input indices for the current timestep of the decoder, and all the encoder - outputs, compute the input at the current timestep. Note: This method is agnostic to - whether the indices are gold indices or the predictions made by the decoder at the last - timestep. - - If we're not using attention, the output of this method is just an embedding of the input - indices. If we are, the output will be a concatentation of the embedding and an attended - average of the encoder inputs. - - Parameters - ---------- - input_indices : torch.LongTensor - Indices of either the gold inputs to the decoder or the predicted labels from the - previous timestep. - decoder_hidden_state : torch.LongTensor, optional (not needed if no attention) - Output of from the decoder at the last time step. Needed only if using attention. - encoder_outputs : torch.LongTensor, optional (not needed if no attention) - Encoder outputs from all time steps. Needed only if using attention. - encoder_outputs_mask : torch.LongTensor, optional (not needed if no attention) - Masks on encoder outputs. Needed only if using attention. - """ - input_indices = input_indices.long() - # input_indices : (batch_size,) since we are processing these one timestep at a time. - # (batch_size, target_embedding_dim) - embedded_input = self._target_embedder(input_indices) - - if self._decoder_attention is not None: - # encoder_outputs : (batch_size, input_sequence_length, encoder_output_dim) - # Ensuring mask is also a FloatTensor. Or else the multiplication within attention will - # complain. - - # important - need to use zero-masking instead of -inf for attention - # I've checked that doing this doesn't significantly increase time - # per batch, but should consider only doing once - encoder_outputs.data.masked_fill_(1 - encoder_outputs_mask.byte().data, 0.0) - - encoder_outputs = 0.5 * encoder_outputs - encoder_outputs_mask = encoder_outputs_mask.float() - encoder_outputs_mask = encoder_outputs_mask[:, :, 0] - # (batch_size, input_sequence_length) - attention_input = torch.cat((decoder_hidden_state, embedded_input), 1) - input_weights = self._decoder_attention( - attention_input, encoder_outputs, encoder_outputs_mask - ) - # (batch_size, input_dim) - attended_input = weighted_sum(encoder_outputs, input_weights) - # (batch_size, input_dim + target_embedding_dim) - return torch.cat((attended_input, embedded_input), -1) - else: - return embedded_input - - @staticmethod - def _get_loss( - logits: torch.LongTensor, targets: torch.LongTensor, target_mask: torch.LongTensor - ) -> torch.LongTensor: - """ - Takes logits (unnormalized outputs from the decoder) of size (batch_size, - num_decoding_steps, num_classes), target indices of size (batch_size, num_decoding_steps+1) - and corresponding masks of size (batch_size, num_decoding_steps+1) steps and computes cross - entropy loss while taking the mask into account. - - The length of ``targets`` is expected to be greater than that of ``logits`` because the - decoder does not need to compute the output corresponding to the last timestep of - ``targets``. This method aligns the inputs appropriately to compute the loss. - - During training, we want the logit corresponding to timestep i to be similar to the target - token from timestep i + 1. That is, the targets should be shifted by one timestep for - appropriate comparison. Consider a single example where the target has 3 words, and - padding is to 7 tokens. - The complete sequence would correspond to w1 w2 w3

- and the mask would be 1 1 1 1 1 0 0 - and let the logits be l1 l2 l3 l4 l5 l6 - We actually need to compare: - the sequence w1 w2 w3

- with masks 1 1 1 1 0 0 - against l1 l2 l3 l4 l5 l6 - (where the input was) w1 w2 w3

- """ - relevant_targets = targets[:, 1:].contiguous() # (batch_size, num_decoding_steps) - # (batch_size, num_decoding_steps) - relevant_mask = target_mask[:, 1:].contiguous() - loss = sequence_cross_entropy_with_logits(logits, relevant_targets, relevant_mask) - return loss diff --git a/jiant/modules/simple_modules.py b/jiant/modules/simple_modules.py deleted file mode 100644 index eba58ce4d..000000000 --- a/jiant/modules/simple_modules.py +++ /dev/null @@ -1,285 +0,0 @@ -import torch -import torch.nn as nn - - -class NullPhraseLayer(nn.Module): - """ Dummy phrase layer that does nothing. Exists solely for API compatibility. """ - - def __init__(self, input_dim: int): - super(NullPhraseLayer, self).__init__() - self.input_dim = input_dim - - def get_input_dim(self): - return self.input_dim - - def get_output_dim(self): - return 0 - - def forward(self, embs, mask): - return None - - -class Pooler(nn.Module): - """ Do pooling, possibly with a projection beforehand """ - - def __init__(self, project=True, d_inp=512, d_proj=512, pool_type="max"): - super(Pooler, self).__init__() - self.project = nn.Linear(d_inp, d_proj) if project else lambda x: x - self.pool_type = pool_type - - def forward(self, sequence, mask): - if len(mask.size()) < 3: - mask = mask.unsqueeze(dim=-1) - pad_mask = mask == 0 - proj_seq = self.project(sequence) # linear project each hid state - if self.pool_type == "max": - proj_seq = proj_seq.masked_fill(pad_mask, -float("inf")) - seq_emb = proj_seq.max(dim=1)[0] - elif self.pool_type == "mean": - proj_seq = proj_seq.masked_fill(pad_mask, 0) - seq_emb = proj_seq.sum(dim=1) / mask.sum(dim=1) - elif self.pool_type == "final": - idxs = mask.expand_as(proj_seq).sum(dim=1, keepdim=True).long() - 1 - seq_emb = proj_seq.gather(dim=1, index=idxs).squeeze(dim=1) - elif self.pool_type == "first": - seq_emb = proj_seq[:, 0] - return seq_emb - - -class Classifier(nn.Module): - """ Logistic regression or MLP classifier """ - - # NOTE: Expects dropout to have already been applied to its input. - - def __init__(self, d_inp, n_classes, cls_type="mlp", dropout=0.2, d_hid=512): - super(Classifier, self).__init__() - if cls_type == "log_reg": - classifier = nn.Linear(d_inp, n_classes) - elif cls_type == "mlp": - classifier = nn.Sequential( - nn.Linear(d_inp, d_hid), - nn.Tanh(), - nn.LayerNorm(d_hid), - nn.Dropout(dropout), - nn.Linear(d_hid, n_classes), - ) - elif cls_type == "fancy_mlp": # What they did in Infersent. - classifier = nn.Sequential( - nn.Linear(d_inp, d_hid), - nn.Tanh(), - nn.LayerNorm(d_hid), - nn.Dropout(dropout), - nn.Linear(d_hid, d_hid), - nn.Tanh(), - nn.LayerNorm(d_hid), - nn.Dropout(p=dropout), - nn.Linear(d_hid, n_classes), - ) - else: - raise ValueError("Classifier type %s not found" % type) - self.classifier = classifier - - def forward(self, seq_emb): - logits = self.classifier(seq_emb) - return logits - - @classmethod - def from_params(cls, d_inp, n_classes, params): - return cls( - d_inp, - n_classes, - cls_type=params["cls_type"], - dropout=params["dropout"], - d_hid=params["d_hid"], - ) - - -class SOPClassifier(nn.Module): - """ - Task head for sentence order prediction task. We implement the pooled output from ALBERT - via a linear layer followed by Tanh activation layer, which is then fed into the - classification linear layer. - """ - - def __init__(self, d_inp, n_classes, params): - super(SOPClassifier, self).__init__() - self.activation = nn.Tanh() - self.pooler = Pooler(d_inp=d_inp, d_proj=d_inp, pool_type=params["pool_type"]) - assert params["cls_type"] == "log_reg", ( - "The ALBERT implementation of the SOP " - "task takes the final layer from the pooled" - "output. Please set cls_type = log_reg." - ) - self.classifier = Classifier.from_params(d_inp, n_classes, params) - - def forward(self, seq_emb, mask): - seq_emb = self.activation(self.pooler(seq_emb, mask)) - logits = self.classifier(seq_emb) - return logits - - -class SingleClassifier(nn.Module): - """ Thin wrapper around a set of modules. For single-sentence classification. """ - - def __init__(self, pooler, classifier): - super(SingleClassifier, self).__init__() - self.pooler = pooler - self.classifier = classifier - - def forward(self, sent, mask, idxs=[]): - """ - This class applies some type of pooling to get a fixed-size vector, - possibly extracts some specific representations from the input sequence - and concatenates those reps to the overall representations, - then passes the whole thing through a classifier. - - args: - - sent (FloatTensor): sequence of hidden states representing a sentence - Assumes batch_size x seq_len x d_emb. - - mask (FloatTensor): binary masking denoting which elements of sent are not padding - - idxs (List[LongTensor]): list of indices of to extract from sent and - concatenate to the post-pooling representation. - For each element in idxs, we extract all the non-pad (0) representations, pool, - and concatenate the resulting fixed size vector to the overall representation. - - returns: - - logits (FloatTensor): logits for classes - """ - - emb = self.pooler(sent, mask) - - # append any specific token representations, e.g. for WiC task - ctx_embs = [] - for idx in idxs: - if len(idx.shape) == 1: - idx = idx.unsqueeze(-1) - if len(idx.shape) == 2: - idx = idx.unsqueeze(-1) - if len(idx.shape) == 3: - assert idx.size(-1) == 1 or idx.size(-1) == sent.size( - -1 - ), "Invalid index dimension!" - idx = idx.expand([-1, -1, sent.size(-1)]).long() - else: - raise ValueError("Invalid dimensions of index tensor!") - - ctx_mask = (idx != 0).float() - # the first element of the mask should never be zero - ctx_mask[:, 0] = 1 - ctx_emb = sent.gather(dim=1, index=idx) * ctx_mask - ctx_emb = ctx_emb.sum(dim=1) / ctx_mask.sum(dim=1) - ctx_embs.append(ctx_emb) - final_emb = torch.cat([emb] + ctx_embs, dim=-1) - logits = self.classifier(final_emb) - return logits - - -class PairClassifier(nn.Module): - """ Thin wrapper around a set of modules. - For sentence pair classification. - Pooler specifies how to aggregate inputted sequence of vectors. - Also allows for use of specific token representations to be addded to the overall - representation - """ - - def __init__(self, pooler, classifier, attn=None): - super(PairClassifier, self).__init__() - self.pooler = pooler - self.classifier = classifier - self.attn = attn - - def forward(self, s1, s2, mask1, mask2, idx1=[], idx2=[]): - """ - This class applies some type of pooling to each of two inputs to get two fixed-size vectors, - possibly extracts some specific representations from the input sequence - and concatenates those reps to the overall representations, - then passes the whole thing through a classifier. - - args: - - s1/s2 (FloatTensor): sequence of hidden states representing a sentence - Assumes batch_size x seq_len x d_emb. - - mask1/mask2 (FloatTensor): binary masking denoting which elements of sent are not padding - - idx{1,2} (List[LongTensor]): list of indices of to extract from sent and - concatenate to the post-pooling representation. - For each element in idxs, we extract all the non-pad (0) representations, pool, - and concatenate the resulting fixed size vector to the overall representation. - - returns: - - logits (FloatTensor): logits for classes - """ - - mask1 = mask1.squeeze(-1) if len(mask1.size()) > 2 else mask1 - mask2 = mask2.squeeze(-1) if len(mask2.size()) > 2 else mask2 - if self.attn is not None: - s1, s2 = self.attn(s1, s2, mask1, mask2) - emb1 = self.pooler(s1, mask1) - emb2 = self.pooler(s2, mask2) - - s1_ctx_embs = [] - for idx in idx1: - if len(idx.shape) == 1: - idx = idx.unsqueeze(-1) - if len(idx.shape) == 2: - idx = idx.unsqueeze(-1) - if len(idx.shape) == 3: - assert idx.size(-1) == 1 or idx.size(-1) == s1.size(-1), "Invalid index dimension!" - idx = idx.expand([-1, -1, s1.size(-1)]).long() - else: - raise ValueError("Invalid dimensions of index tensor!") - - s1_ctx_mask = (idx != 0).float() - # the first element of the mask should never be zero - s1_ctx_mask[:, 0] = 1 - s1_ctx_emb = s1.gather(dim=1, index=idx) * s1_ctx_mask - s1_ctx_emb = s1_ctx_emb.sum(dim=1) / s1_ctx_mask.sum(dim=1) - s1_ctx_embs.append(s1_ctx_emb) - emb1 = torch.cat([emb1] + s1_ctx_embs, dim=-1) - - s2_ctx_embs = [] - for idx in idx2: - if len(idx.shape) == 1: - idx = idx.unsqueeze(-1) - if len(idx.shape) == 2: - idx = idx.unsqueeze(-1) - if len(idx.shape) == 3: - assert idx.size(-1) == 1 or idx.size(-1) == s2.size(-1), "Invalid index dimension!" - idx = idx.expand([-1, -1, s2.size(-1)]).long() - else: - raise ValueError("Invalid dimensions of index tensor!") - - s2_ctx_mask = (idx != 0).float() - # the first element of the mask should never be zero - s2_ctx_mask[:, 0] = 1 - s2_ctx_emb = s2.gather(dim=1, index=idx) * s2_ctx_mask - s2_ctx_emb = s2_ctx_emb.sum(dim=1) / s2_ctx_mask.sum(dim=1) - s2_ctx_embs.append(s2_ctx_emb) - emb2 = torch.cat([emb2] + s2_ctx_embs, dim=-1) - - pair_emb = torch.cat([emb1, emb2, torch.abs(emb1 - emb2), emb1 * emb2], 1) - logits = self.classifier(pair_emb) - return logits - - -class TokenProjectionEncoder(nn.Module): - """ Applies projection to each token representation """ - - def __init__(self, d_inp=512): - super(TokenProjectionEncoder, self).__init__() - self.project = nn.Linear(d_inp, 1) - - def forward(self, sequence, mask): - logits = self.project(sequence).squeeze(-1) - return logits - - -class TokenMultiProjectionEncoder(nn.Module): - """ Applies multiple projections to each token representation """ - - def __init__(self, projection_names, d_inp=512): - super(TokenMultiProjectionEncoder, self).__init__() - self.projections = nn.ModuleDict( - {name: TokenProjectionEncoder(d_inp=d_inp) for name in projection_names} - ) - - def forward(self, sequence, mask): - return {name: projection(sequence, mask) for name, projection in self.projections.items()} diff --git a/jiant/modules/span_modules.py b/jiant/modules/span_modules.py deleted file mode 100644 index 09ed99aee..000000000 --- a/jiant/modules/span_modules.py +++ /dev/null @@ -1,186 +0,0 @@ -# Implementation of span classification modules - -from typing import Dict, Any - -import torch -import torch.nn as nn -import torch.nn.functional as F -from allennlp.modules.span_extractors import EndpointSpanExtractor, SelfAttentiveSpanExtractor - -from jiant.tasks.tasks import Task -from jiant.modules.simple_modules import Classifier -from jiant.utils.utils import get_batch_size, format_output - - -class SpanClassifierModule(nn.Module): - """ - Build span classifier components as a sub-module. - Classifier that allows for spans and text as input. - Use same classifier code as build_single_sentence_module, - except we'll use span indices to extract span representations, - and use these as input to the classifier. - """ - - def _make_span_extractor(self): - if self.span_pooling == "attn": - return SelfAttentiveSpanExtractor(self.proj_dim) - else: - return EndpointSpanExtractor(self.proj_dim, combination=self.span_pooling) - - def _make_cnn_layer(self, d_inp): - """ - Make a CNN layer as a projection of local context. - CNN maps [batch_size, max_len, d_inp] - to [batch_size, max_len, proj_dim] with no change in length. - """ - k = 1 + 2 * self.cnn_context - padding = self.cnn_context - return nn.Conv1d( - d_inp, - self.proj_dim, - kernel_size=k, - stride=1, - padding=padding, - dilation=1, - groups=1, - bias=True, - ) - - def __init__(self, task, d_inp: int, task_params, num_spans=2): - assert num_spans > 0, "Please set num_spans to be more than 0" - super(SpanClassifierModule, self).__init__() - # Set config options needed for forward pass. - self.loss_type = task_params["cls_loss_fn"] - self.span_pooling = task_params["cls_span_pooling"] - self.cnn_context = task_params.get("cnn_context", 0) - self.num_spans = num_spans - self.proj_dim = task_params["d_hid"] - self.projs = torch.nn.ModuleList() - - for i in range(num_spans): - # create a word-level pooling layer operator - proj = self._make_cnn_layer(d_inp) - self.projs.append(proj) - self.span_extractors = torch.nn.ModuleList() - - # Lee's self-pooling operator (https://arxiv.org/abs/1812.10860) - for i in range(num_spans): - span_extractor = self._make_span_extractor() - self.span_extractors.append(span_extractor) - - # Classifier gets concatenated projections of spans. - clf_input_dim = self.span_extractors[1].get_output_dim() * num_spans - self.classifier = Classifier.from_params(clf_input_dim, task.n_classes, task_params) - - def forward( - self, - batch: Dict, - sent_embs: torch.Tensor, - sent_mask: torch.Tensor, - task: Task, - predict: bool, - cuda_devices: Any, - ) -> Dict: - """ - Run forward pass. - Expects batch to have the following entries: - 'input' : [batch_size, max_len, emb_size] - 'labels' : [batch_size, num_targets] of label indices - 'span1s' : [batch_size, 1, 2], span indices - 'span2s' : [batch_size, 1, 2], span indices - . - . - . - 'span_ts': [batch_size, 1, 2], span indices - - Parameters - ------------------------------- - batch: dict(str -> Tensor) with entries described above. - sent_embs: [batch_size, max_len, repr_dim] Tensor - sent_mask: [batch_size, max_len, 1] Tensor of {0,1} - task: Task - predict: whether or not to generate predictions - This learns different span pooling operators for each span. - - Returns - ------------------------------- - out: dict(str -> Tensor) - """ - out = {} - - # Apply projection CNN layer for each span of the input sentence - sent_embs_t = sent_embs.transpose(1, 2) # needed for CNN layer - se_projs = [] - for i in range(self.num_spans): - se_proj = self.projs[i](sent_embs_t).transpose(2, 1).contiguous() - se_projs.append(se_proj) - - span_embs = torch.Tensor([]).cuda() if torch.cuda.is_available() else torch.Tensor([]) - out["n_exs"] = get_batch_size(batch, cuda_devices) - _kw = dict(sequence_mask=sent_mask.long()) - for i in range(self.num_spans): - # spans are [batch_size, num_targets, span_modules] - span_emb = self.span_extractors[i](se_projs[i], batch["span" + str(i + 1) + "s"], **_kw) - span_embs = torch.cat([span_embs, span_emb], dim=2) - - # [batch_size, num_targets, n_classes] - logits = self.classifier(span_embs) - out["logits"] = logits - - # Compute loss if requested. - if "labels" in batch: - logits = logits.squeeze(dim=1) - out["logits"] = logits - out["loss"] = format_output( - self.compute_loss(logits, batch["labels"], task), cuda_devices - ) - - if predict: - # Return preds as a list. - preds = self.get_predictions(logits) - out["preds"] = preds - return out - - def get_predictions(self, logits: torch.Tensor): - """ - Return class probabilities, same shape as logits. - - Parameters - ------------------------------- - logits: [batch_size, num_targets, n_classes] - - Returns - ------------------------------- - probs: [batch_size, num_targets, n_classes] - """ - if self.loss_type == "sigmoid": - return torch.sigmoid(logits) - elif self.loss_type == "softmax": - logits = logits.squeeze(dim=1) - pred = torch.nn.Softmax(dim=1)(logits) - pred = torch.argmax(pred, dim=1) - return pred - else: - raise ValueError( - "Unsupported loss type '%s' " "for span classification." % self.loss_type - ) - - def compute_loss(self, logits: torch.Tensor, labels: torch.Tensor, task): - """ - Paramters - ------------------------------- - logits: [total_num_targets, n_classes] Tensor of float scores - labels: [total_num_targets, n_classes] Tensor of sparse binary targets - - Returns - ------------------------------- - loss: scalar Tensor - """ - if self.loss_type == "sigmoid": - return F.binary_cross_entropy(torch.sigmoid(logits), labels.float()) - elif self.loss_type == "softmax": - return F.cross_entropy(logits, labels.long()) - else: - raise ValueError( - "Unsupported loss type '%s' " "for span classification." % self.loss_type - ) diff --git a/jiant/preprocess.py b/jiant/preprocess.py deleted file mode 100644 index e06fccbf2..000000000 --- a/jiant/preprocess.py +++ /dev/null @@ -1,811 +0,0 @@ -"""Preprocessing functions and pipeline - -The pipeline is three steps - 1) create / load tasks, which includes - a) load raw data - b) tokenize raw data - 2) create / load all vocabularies (word, char, task-specific target vocabs) - a) count tokens of a vocab - b) take the N most frequent tokens - 3) index all the data using appropriate indexers - We save indexed data to streamable Records to save memory. -""" -import _pickle as pkl # :( -import copy -import io -import logging as log -import os -import sys -from collections import defaultdict -from typing import List, Dict, Union, Any - -import numpy as np -import torch -from allennlp.data import Vocabulary -from allennlp.data.token_indexers import ( - ELMoTokenCharactersIndexer, - SingleIdTokenIndexer, - TokenCharactersIndexer, -) - -from jiant.huggingface_transformers_interface import ( - input_module_uses_transformers, - input_module_tokenizer_name, -) -from transformers import ( - BertTokenizer, - RobertaTokenizer, - AlbertTokenizer, - XLNetTokenizer, - OpenAIGPTTokenizer, - GPT2Tokenizer, - TransfoXLTokenizer, - XLMTokenizer, -) - -from jiant.tasks import ( - ALL_DIAGNOSTICS, - ALL_COLA_NPI_TASKS, - ALL_GLUE_TASKS, - ALL_SUPERGLUE_TASKS, - ALL_NLI_PROBING_TASKS, - ALL_SEQ2SEQ_TASKS, -) -from jiant.tasks import REGISTRY as TASKS_REGISTRY -from jiant.tasks.seq2seq import Seq2SeqTask -from jiant.tasks.tasks import SequenceGenerationTask, Task -from jiant.tasks.lm import MaskedLanguageModelingTask -from jiant.utils import config, serialize, utils, options -from jiant.utils.options import parse_task_list_arg - -# NOTE: these are not that same as AllenNLP SOS, EOS tokens -SOS_TOK, EOS_TOK = "", "" -# NOTE: pad and unk tokens are created by AllenNLP vocabs by default -SPECIALS = [SOS_TOK, EOS_TOK] -UNK_TOK = "@@UNKNOWN@@" # AllenNLP unk token - -ALL_SPLITS = ["train", "val", "test"] - - -def _get_serialized_record_path(task_name, split, preproc_dir): - """Get the canonical path for a serialized task split.""" - serialized_record_path = os.path.join(preproc_dir, "{:s}__{:s}_data".format(task_name, split)) - return serialized_record_path - - -def _get_instance_generator(task_name, split, preproc_dir, fraction=None): - """Get a lazy generator for the given task and split. - - Args: - task_name: (string), task name - split: (string), split name ('train', 'val', or 'test') - preproc_dir: (string) path to preprocessing dir - fraction: if set to a float between 0 and 1, load only the specified percentage - of examples. Hashing is used to ensure that the same examples are loaded each - epoch. - - Returns: - serialize.RepeatableIterator yielding Instance objects - """ - filename = _get_serialized_record_path(task_name, split, preproc_dir) - assert os.path.isfile(filename), "Record file '%s' not found!" % filename - return serialize.read_records(filename, repeatable=True, fraction=fraction) - - -def _indexed_instance_generator(instance_iter, vocab): - """Yield indexed instances. Instances are modified in-place. - - TODO(iftenney): multiprocess the $%^& out of this. - - Args: - instance_iter: iterable(Instance) of examples - vocab: Vocabulary for use in indexing - - Yields: - Instance with indexed fields. - """ - for instance in instance_iter: - instance.index_fields(vocab) - # Strip token fields to save memory and disk. - del_field_tokens(instance) - yield instance - - -def del_field_tokens(instance): - """ Save memory by deleting the tokens that will no longer be used. - Only works if Instances have fields 'input1' and 'input2'. - All other fields will keep their tokens in memory. - - Args: - instance: AllenNLP Instance. Modified in-place. - """ - if "input1" in instance.fields: - field = instance.fields["input1"] - del field.tokens - if "input2" in instance.fields: - field = instance.fields["input2"] - del field.tokens - - -def _index_split(task, split, indexers, vocab, record_file, model_preprocessing_interface): - """Index instances and stream to disk. - Args: - task: Task instance - split: (string), 'train', 'val', or 'test' - indexers: dict of token indexers - vocab: Vocabulary instance - record_file: (string) file to write serialized Instances to - model_preprocessing_interface: packed information from model that effects the task data, - including whether to concatenate sentence pair, and how to mark the sentence boundry - """ - log_prefix = "\tTask %s (%s)" % (task.name, split) - log.info("%s: Indexing from scratch.", log_prefix) - split_text = task.get_split_text(split) - instance_iter = task.process_split(split_text, indexers, model_preprocessing_interface) - if hasattr(instance_iter, "__len__"): # if non-lazy - log.warn( - "%s: non-lazy Instance generation. You'll want to refactor " - "%s.process_split to return a lazy iterator.", - log_prefix, - type(task).__name__, - ) - log.info("%s: %d examples to index", log_prefix, len(instance_iter)) - # Copy so that we don't store indexed data in memory. - # TODO: remove this case and stream everything. - instance_iter = utils.copy_iter(instance_iter) - - # Counter for lazy-loaded data, so we can log the # of elements. - _instance_counter = 0 - - def _counter_iter(elems): - nonlocal _instance_counter - for elem in elems: - _instance_counter += 1 - yield elem - - instance_iter = _counter_iter(instance_iter) - - # Actually call generators and stream to disk. - serialize.write_records(_indexed_instance_generator(instance_iter, vocab), record_file) - log.info("%s: Saved %d instances to %s", log_prefix, _instance_counter, record_file) - - -def _find_cached_file( - exp_dir: str, global_exp_cache_dir: str, relative_path: str, log_prefix: str = "" -) -> bool: - """Find a cached file. - - Look in local exp_dir first, then in global_exp_cache_dir. If found in the - global dir, make a symlink in the local dir pointing to the global one. - - Args: - exp_dir: (string) local experiment dir - global_exp_cache_dir: (string) global experiment cache - relative_path: (string) relative path to file, from exp_dir - log_prefix: (string) prefix for logging info - - Returns: - True if file was found in either location. - """ - if log_prefix: - log_prefix = log_prefix + ": " - # Try in local preproc dir. - local_file = os.path.join(exp_dir, relative_path) - if os.path.isfile(local_file) or os.path.islink(local_file): - log.info("%sFound preprocessed copy in %s", log_prefix, local_file) - return True - # Try in global preproc dir; if found, make a symlink. - global_file = os.path.join(global_exp_cache_dir, relative_path) - if os.path.exists(global_file): - log.info("%sFound (global) preprocessed copy in %s", log_prefix, global_file) - os.symlink(global_file, local_file) - log.info("%sCreated symlink: %s -> %s", log_prefix, local_file, global_file) - return True - return False - - -def _build_embeddings(args, vocab, emb_file: str): - """ Build word embeddings from scratch (as opposed to loading them from a pickle), - using precomputed fastText / GloVe embeddings. """ - - # Load all the word embeddings based on vocabulary - log.info("\tBuilding embeddings from scratch.") - word_v_size, unk_idx = vocab.get_vocab_size("tokens"), vocab.get_token_index(vocab._oov_token) - embeddings = np.random.randn(word_v_size, args.d_word) - - if args.word_embs_file: - with io.open( - args.word_embs_file, "r", encoding="utf-8", newline="\n", errors="ignore" - ) as vec_fh: - for line in vec_fh: - word, vec = line.split(" ", 1) - idx = vocab.get_token_index(word) - if idx != unk_idx: - embeddings[idx] = np.array(list(map(float, vec.split()))) - embeddings[vocab.get_token_index(vocab._padding_token)] = 0.0 - - embeddings = torch.FloatTensor(embeddings) - log.info("\tFinished loading embeddings") - - # Save/cache the word embeddings - pkl.dump(embeddings, open(emb_file, "wb")) - log.info("\tSaved embeddings to %s", emb_file) - return embeddings - - -def _build_vocab(args: config.Params, tasks: List[Task], vocab_path: str): - """Build vocabulary from scratch - - Read data from all tasks into namespaces, optionally add special vocab items, and save - vocabulary file. - - Note - ---- - task-specific target vocabulary should be counted in the task object - and provided via `task.all_labels()`. The namespace should be task-specific, - i.e. not something generic like "targets". - - Parameters - ---------- - args : config.Params - config map - tasks : List[Task] - list of Task from which to build vocab - vocab_path : str - vocab file save path - - """ - log.info("\tBuilding vocab from scratch.") - max_v_sizes = {"word": args.max_word_v_size, "char": args.max_char_v_size} - word2freq, char2freq = get_words(tasks) - vocab = get_vocab(word2freq, char2freq, max_v_sizes) - for task in tasks: # add custom label namespaces - # TODO: surface more docs for add_task_label_vocab: - add_task_label_vocab(vocab, task) - - if args.force_include_wsj_vocabulary: - # Add WSJ full vocabulary for PTB F1 parsing tasks. - add_wsj_vocab(vocab, args.data_dir) - if input_module_uses_transformers(args.input_module): - # Add pre-computed vocabulary of corresponding tokenizer for transformers models. - add_transformers_vocab(vocab, args.tokenizer) - - vocab.save_to_files(vocab_path) - log.info("\tSaved vocab to %s", vocab_path) - # del word2freq, char2freq, target2freq - - -def build_indexers(args): - indexers = {} - if args.input_module in ["scratch", "glove", "fastText"]: - indexers["words"] = SingleIdTokenIndexer() - elif args.input_module in ["elmo", "elmo-chars-only"]: - indexers["elmo"] = ELMoTokenCharactersIndexer("elmo") - assert args.tokenizer in {"", "MosesTokenizer"} - - if args.char_embs: - indexers["chars"] = TokenCharactersIndexer("chars") - if args.cove: - assert args.tokenizer == "MosesTokenizer", ( - f"CoVe model expects Moses tokenization (MosesTokenizer);" - " you are using args.tokenizer = {args.tokenizer}" - ) - - if input_module_uses_transformers(args.input_module): - assert ( - not indexers - ), "transformers modules like BERT/XLNet are not supported alongside other " - "indexers due to tokenization." - assert args.tokenizer == args.input_module, ( - "transformers models use custom tokenization for each model, so tokenizer " - "must match the specified model." - ) - tokenizer_name = input_module_tokenizer_name(args.input_module) - indexers[tokenizer_name] = SingleIdTokenIndexer(tokenizer_name) - return indexers - - -def build_tasks( - args: config.Params, cuda_device: Any -) -> (List[Task], List[Task], Vocabulary, Union[np.ndarray, float]): - """Main logic for preparing tasks: - - 1. create or load the tasks - 2. configure classifiers for tasks - 3. set up indexers - 4. build and save vocab to disk - 5. load vocab from disk - 6. if specified, load word embeddings - 7. set up ModelPreprocessingInterface (MPI) to handle model-specific preprocessing - 8. index tasks using vocab and task-specific MPI, save to disk. - 9. return: task data lazy-loaders in phase-specific lists w/ vocab, and word embeddings - - Parameters - ---------- - args : Params - config map - - Returns - ------- - List[Task] - list of pretrain Tasks. - List[Task] - list of target Tasks. - allennlp.data.Vocabulary - vocabulary from task data. - Union[np.ndarray, float] - Word embeddings. - - """ - # 1) create / load tasks - tasks, pretrain_task_names, target_task_names = get_tasks(args, cuda_device) - for task in tasks: - task_classifier = config.get_task_attr(args, task.name, "use_classifier") - setattr(task, "_classifier_name", task_classifier if task_classifier else task.name) - - tokenizer_names = {task.name: task.tokenizer_name for task in tasks} - assert not len(set(tokenizer_names.values())) > 1, ( - f"Error: mixing tasks with different tokenizers!" " Tokenizations: {tokenizer_names:s}" - ) - - # 2) build / load vocab and indexers - indexers = build_indexers(args) - - vocab_path = os.path.join(args.exp_dir, "vocab") - if args.reload_vocab or not os.path.exists(vocab_path): - _build_vocab(args, tasks, vocab_path) - - # Always load vocab from file. - vocab = Vocabulary.from_files(vocab_path) - log.info("\tLoaded vocab from %s", vocab_path) - - for namespace, mapping in vocab._index_to_token.items(): - log.info("\tVocab namespace %s: size %d", namespace, len(mapping)) - log.info("\tFinished building vocab.") - args.max_word_v_size = vocab.get_vocab_size("tokens") - args.max_char_v_size = vocab.get_vocab_size("chars") - - # 3) build / load word vectors - word_embs = None - if args.input_module in ["glove", "fastText"]: - emb_file = os.path.join(args.exp_dir, "embs.pkl") - if args.reload_vocab or not os.path.exists(emb_file): - word_embs = _build_embeddings(args, vocab, emb_file) - else: # load from file - word_embs = pkl.load(open(emb_file, "rb")) - log.info("Trimmed word embeddings: %s", str(word_embs.size())) - - # 4) Set up model_preprocessing_interface - model_preprocessing_interface = ModelPreprocessingInterface(args) - - # 5) Index tasks using vocab (if preprocessed copy not available). - preproc_dir = os.path.join(args.exp_dir, "preproc") - utils.maybe_make_dir(preproc_dir) - reindex_tasks = parse_task_list_arg(args.reindex_tasks) - utils.assert_for_log( - not (args.reload_indexing and not reindex_tasks), - 'Flag reload_indexing was set, but no tasks are set to reindex (use -o "args.reindex_tasks' - ' = "task1,task2,..."")', - ) - - for task in tasks: - force_reindex = args.reload_indexing and task.name in reindex_tasks - for split in ALL_SPLITS: - log_prefix = "\tTask '%s', split '%s'" % (task.name, split) - relative_path = _get_serialized_record_path(task.name, split, "preproc") - cache_found = _find_cached_file( - args.exp_dir, args.global_ro_exp_dir, relative_path, log_prefix=log_prefix - ) - if force_reindex or not cache_found: - # Re-index from scratch. - record_file = _get_serialized_record_path(task.name, split, preproc_dir) - if os.path.exists(record_file) and os.path.islink(record_file): - os.remove(record_file) - - _index_split( - task, split, indexers, vocab, record_file, model_preprocessing_interface - ) - - # Delete in-memory data - we'll lazy-load from disk later. - # TODO: delete task.{split}_data_text? - - log.info("\tFinished indexing tasks") - - # 6) Initialize tasks with data iterators. - pretrain_tasks = [] - target_tasks = [] - for task in tasks: - # Replace lists of instances with lazy generators from disk. - task.set_instance_iterable( - split_name="val", - instance_iterable=_get_instance_generator(task.name, "val", preproc_dir), - ) - task.set_instance_iterable( - split_name="test", - instance_iterable=_get_instance_generator(task.name, "test", preproc_dir), - ) - # When using pretrain_data_fraction, we need modified iterators for use - # only on training datasets at pretraining time. - if task.name in pretrain_task_names: - log.info("\tCreating trimmed pretraining-only version of " + task.name + " train.") - task.set_instance_iterable( - split_name="train", - instance_iterable=_get_instance_generator( - task.name, "train", preproc_dir, fraction=args.pretrain_data_fraction - ), - phase="pretrain", - ) - pretrain_tasks.append(task) - # When using target_train_data_fraction, we need modified iterators - # only for training datasets at do_target_task_training time. - if task.name in target_task_names: - log.info("\tCreating trimmed target-only version of " + task.name + " train.") - task.set_instance_iterable( - split_name="train", - instance_iterable=_get_instance_generator( - task.name, "train", preproc_dir, fraction=args.target_train_data_fraction - ), - phase="target_train", - ) - target_tasks.append(task) - - log.info("\t Training on %s", ", ".join(pretrain_task_names)) - log.info("\t Evaluating on %s", ", ".join(target_task_names)) - return pretrain_tasks, target_tasks, vocab, word_embs - - -def _get_task(name: str, args: config.Params, data_path: str, scratch_path: str) -> Task: - """Get task object from disk if available. Else construct, prepare and save a new task object. - - Parameters - ---------- - name : str - task name to load. - args : config.Params - param handler object. - data_path : str - base data directory. - scratch_path : str - where to save Task objects. - - Returns - ------- - Task - loaded task object. - - """ - assert name in TASKS_REGISTRY, f"Task '{name:s}' not found!" - task_cls, rel_path, task_kw = TASKS_REGISTRY[name] - pkl_path = os.path.join(scratch_path, "tasks", f"{name:s}.{args.tokenizer:s}.pkl") - # TODO: refactor to always read from disk, even if task is constructed - # here. This should avoid subtle bugs from deserialization issues. - if os.path.isfile(pkl_path) and not args.reload_tasks: - task = pkl.load(open(pkl_path, "rb")) - log.info("\tLoaded existing task %s", name) - else: - log.info("\tCreating task %s from scratch.", name) - # These tasks take an additional kwarg. - if name == "nli-prob" or name == "nli-alt": - # TODO: remove special case, replace with something general - # to pass custom loader args to task. - task_kw["probe_path"] = args["nli-prob"].probe_path - if name in ALL_SEQ2SEQ_TASKS: - task_kw["max_targ_v_size"] = args.max_targ_word_v_size - task_src_path = os.path.join(data_path, rel_path) - task = task_cls( - task_src_path, - max_seq_len=args.max_seq_len, - name=name, - tokenizer_name=args.tokenizer, - **task_kw, - ) - task.load_data() - utils.maybe_make_dir(os.path.dirname(pkl_path)) - pkl.dump(task, open(pkl_path, "wb")) - - return task - - -def get_task_without_loading_data(task_name, args): - """ Build a task without loading data """ - task_cls, rel_path, task_kw = TASKS_REGISTRY[task_name] - task = task_cls( - path=None, - max_seq_len=args.max_seq_len, - name=task_name, - tokenizer_name=args.tokenizer, - **task_kw, - ) - return task - - -def get_tasks(args: config.Params, cuda_device: Any) -> (List[Task], List[str], List[str]): - """Get and save tasks: - - 1. Set up task storage file paths - 2. Parse config for task names - 3. Load (or build and save) task objects - 4. Call counting methods on task objects - 5. Log example-count stats for tasks. - - Parameters - ---------- - args : config.Params - config map. - - Returns - ------- - List[Task] - list of all loaded Tasks. - List[str] - pretrain task names. - List[str] - target task names. - - """ - data_path = args.data_dir - scratch_path = args.exp_dir - - pretrain_task_names = parse_task_list_arg(args.pretrain_tasks) - target_task_names = parse_task_list_arg(args.target_tasks) - # TODO: We don't want diagnostic tasks in train_task_names - # but want to support glue/superglue task macros. - pretrain_task_names = list(filter(lambda x: x not in ALL_DIAGNOSTICS, pretrain_task_names)) - - task_names = sorted(set(pretrain_task_names + target_task_names)) - assert data_path is not None - scratch_path = scratch_path or data_path - log.info("Writing pre-preprocessed tasks to %s", scratch_path) - - tasks = [] - for name in task_names: - task = _get_task(name, args, data_path=data_path, scratch_path=scratch_path) - tasks.append(task) - - # Count examples, store in example_counts. - if task.example_counts is None: - task.count_examples() - log.info( - "\tTask '%s': %s", - task.name, - " ".join(("|%s|=%d" % kv for kv in task.example_counts.items())), - ) - - log.info("\tFinished loading tasks: %s.", " ".join([task.name for task in tasks])) - return tasks, pretrain_task_names, target_task_names - - -def get_words(tasks: List[Task]) -> (Dict[str, int], Dict[str, int]): - """Get all words for all tasks for all splits for all sentences across all tasks. - - Parameters - ---------- - tasks : List[Task] - List of tasks to process. - - Returns - ------- - Dict[str, int] - Dictionary storing word frequencies across all tasks. - Dict[str, int] - Dictionary storing char frequencies across all tasks. - - """ - word2freq, char2freq = defaultdict(int), defaultdict(int) - - def update_vocab_freqs(sentence): - """Update counts for words in the sentence""" - for word in sentence: - word2freq[word] += 1 - for char in list(word): - char2freq[char] += 1 - return - - for task in tasks: - log.info("\tCounting units for task %s.", task.name) - if isinstance(task, Seq2SeqTask): - for src_sent, tgt_sent in task.get_sentences(): - update_vocab_freqs(src_sent) - else: - for sentence in task.get_sentences(): - update_vocab_freqs(sentence) - - return word2freq, char2freq - - -def get_vocab( - word2freq: Dict[str, int], char2freq: Dict[str, int], max_v_sizes: Dict[str, int] -) -> Vocabulary: - """Build vocabulary by selecting the most frequent tokens - - Parameters - ---------- - word2freq : Dict[str, int] - Dict mapping words to frequencies. - char2freq : Dict[str, int] - Dict mapping chars to frequencies. - max_v_sizes : dict[str: int] - Dict used to set max vocab size for each token namespace. - - Returns - ------- - allennlp.data.Vocabulary - vocab containing word and char namespaces. - - """ - vocab = Vocabulary(counter=None, max_vocab_size=max_v_sizes) - for special in SPECIALS: - vocab.add_token_to_namespace(special, "tokens") - - words_by_freq = [(word, freq) for word, freq in word2freq.items()] - words_by_freq.sort(key=lambda x: x[1], reverse=True) - for word, _ in words_by_freq[: max_v_sizes["word"]]: - vocab.add_token_to_namespace(word, "tokens") - - chars_by_freq = [(char, freq) for char, freq in char2freq.items()] - chars_by_freq.sort(key=lambda x: x[1], reverse=True) - for char, _ in chars_by_freq[: max_v_sizes["char"]]: - vocab.add_token_to_namespace(char, "chars") - - return vocab - - -def add_task_label_vocab(vocab, task): - """Add custom task labels to a separate namespace. - - If task has a 'get_all_labels' method, call that to get a list of labels - to populate the _labels vocabulary namespace. - - This is the recommended way to implement multiclass models: in your task's - process_split code, make instances that use LabelFields with the task label - namespace, e.g.: - label_namespace = "%s_labels" % self.name - label = LabelField(label_string, label_namespace=label_namespace) - This will cause them to be properly indexed by the Vocabulary. - - This can then be accessed when generating Instances, either via a custom - Indexer or by invoking the namespace when creating a LabelField. - """ - if not hasattr(task, "get_all_labels"): - return - utils.assert_for_log( - hasattr(task, "_label_namespace"), - "Task %s is missing method `_label_namespace`!" % task.name, - ) - namespace = task._label_namespace - if namespace is None: - return - log.info("\tTask '%s': adding vocab namespace '%s'", task.name, namespace) - - for label in task.get_all_labels(): - vocab.add_token_to_namespace(label, namespace) - - -def add_transformers_vocab(vocab, tokenizer_name): - """Add vocabulary from tokenizers in transformers for use with pre-tokenized data. - - These tokenizers have a convert_tokens_to_ids method, but this doesn't do - anything special, so we can just use the standard indexers. - """ - do_lower_case = "uncased" in tokenizer_name - - if tokenizer_name.startswith("bert-"): - tokenizer = BertTokenizer.from_pretrained(tokenizer_name, do_lower_case=do_lower_case) - elif tokenizer_name.startswith("roberta-") or tokenizer_name.startswith("nyu-mll/roberta-"): - tokenizer = RobertaTokenizer.from_pretrained(tokenizer_name) - elif tokenizer_name.startswith("albert-"): - tokenizer = AlbertTokenizer.from_pretrained(tokenizer_name) - elif tokenizer_name.startswith("xlnet-"): - tokenizer = XLNetTokenizer.from_pretrained(tokenizer_name, do_lower_case=do_lower_case) - elif tokenizer_name.startswith("openai-gpt"): - tokenizer = OpenAIGPTTokenizer.from_pretrained(tokenizer_name) - elif tokenizer_name.startswith("gpt2"): - tokenizer = GPT2Tokenizer.from_pretrained(tokenizer_name) - elif tokenizer_name.startswith("transfo-xl-"): - tokenizer = TransfoXLTokenizer.from_pretrained(tokenizer_name) - elif tokenizer_name.startswith("xlm-"): - tokenizer = XLMTokenizer.from_pretrained(tokenizer_name) - - if ( - tokenizer_name.startswith("openai-gpt") - or tokenizer_name.startswith("gpt2") - or tokenizer_name.startswith("transo-xl-") - ): - tokenizer.add_special_tokens( - {"bos_token": "", "sep_token": "", "cls_token": ""} - ) - # TODO: this is another place can be simplified by "model-before-preprocess" reorganization - # we can pass tokenizer created in model here, see issue - - vocab_size = len(tokenizer) - # do not use tokenizer.vocab_size, it does not include newly added token - - ordered_vocab = tokenizer.convert_ids_to_tokens(range(vocab_size)) - log.info("Added transformers vocab (%s): %d tokens", tokenizer_name, len(ordered_vocab)) - for word in ordered_vocab: - vocab.add_token_to_namespace(word, input_module_tokenizer_name(tokenizer_name)) - - -def add_wsj_vocab(vocab, data_dir, namespace="tokens"): - """Add WSJ vocabulary for PTB parsing models.""" - wsj_vocab_path = os.path.join(data_dir, "WSJ/tokens.txt") - # To create the tokens.txt file: Run only WSJ LM baseline on jiant, and - # duplicate the vocab file generated. - assert os.path.exists(wsj_vocab_path), "WSJ vocab file doesn't exist." - wsj_tokens = open(wsj_vocab_path) - for line in wsj_tokens.readlines(): - vocab.add_token_to_namespace(line.strip(), namespace) - log.info("\tAdded WSJ vocabulary from %s", wsj_tokens) - - -class ModelPreprocessingInterface(object): - """ This class holds parts of preprocessing that is model-specific - members: - - model_flags: Dict[str, bool], model-specific flags that may be used in task preprocessing - boundary_token_fn: (list[str], list[str] (optional) -> list[str]): - A function that appliese the appropriate EOS/SOS/SEP/CLS tokens to token sequence or - token sequence pair for most tasks. - lm_boundary_token_fn: (list[str] -> list[str]): - A function that appliese the appropriate EOS/SOS/SEP/CLS tokens to a token sequence for - language modeling tasks. - - """ - - def __init__(self, args): - boundary_token_fn = None - lm_boundary_token_fn = None - - if args.input_module.startswith("bert-"): - from jiant.huggingface_transformers_interface.modules import BertEmbedderModule - - boundary_token_fn = BertEmbedderModule.apply_boundary_tokens - elif args.input_module.startswith("roberta-") or args.input_module.startswith( - "nyu-mll/roberta-" - ): - from jiant.huggingface_transformers_interface.modules import RobertaEmbedderModule - - boundary_token_fn = RobertaEmbedderModule.apply_boundary_tokens - elif args.input_module.startswith("albert-"): - from jiant.huggingface_transformers_interface.modules import AlbertEmbedderModule - - boundary_token_fn = AlbertEmbedderModule.apply_boundary_tokens - elif args.input_module.startswith("xlnet-"): - from jiant.huggingface_transformers_interface.modules import XLNetEmbedderModule - - boundary_token_fn = XLNetEmbedderModule.apply_boundary_tokens - elif args.input_module.startswith("openai-gpt"): - from jiant.huggingface_transformers_interface.modules import OpenAIGPTEmbedderModule - - boundary_token_fn = OpenAIGPTEmbedderModule.apply_boundary_tokens - lm_boundary_token_fn = OpenAIGPTEmbedderModule.apply_lm_boundary_tokens - elif args.input_module.startswith("gpt2"): - from jiant.huggingface_transformers_interface.modules import GPT2EmbedderModule - - boundary_token_fn = GPT2EmbedderModule.apply_boundary_tokens - lm_boundary_token_fn = GPT2EmbedderModule.apply_lm_boundary_tokens - elif args.input_module.startswith("transfo-xl-"): - from jiant.huggingface_transformers_interface.modules import TransfoXLEmbedderModule - - boundary_token_fn = TransfoXLEmbedderModule.apply_boundary_tokens - lm_boundary_token_fn = TransfoXLEmbedderModule.apply_lm_boundary_tokens - elif args.input_module.startswith("xlm-"): - from jiant.huggingface_transformers_interface.modules import XLMEmbedderModule - - boundary_token_fn = XLMEmbedderModule.apply_boundary_tokens - else: - boundary_token_fn = utils.apply_standard_boundary_tokens - - self.boundary_token_fn = boundary_token_fn - if lm_boundary_token_fn is not None: - self.lm_boundary_token_fn = lm_boundary_token_fn - else: - self.lm_boundary_token_fn = boundary_token_fn - - from jiant.models import input_module_uses_pair_embedding, input_module_uses_mirrored_pair - - self.model_flags = {} - self.model_flags["uses_pair_embedding"] = input_module_uses_pair_embedding( - args.input_module - ) - self.model_flags["uses_mirrored_pair"] = input_module_uses_mirrored_pair(args.input_module) diff --git a/jiant/metrics/__init__.py b/jiant/proj/__init__.py similarity index 100% rename from jiant/metrics/__init__.py rename to jiant/proj/__init__.py diff --git a/jiant/modules/__init__.py b/jiant/proj/main/__init__.py similarity index 100% rename from jiant/modules/__init__.py rename to jiant/proj/main/__init__.py diff --git a/probing/__init__.py b/jiant/proj/main/components/__init__.py similarity index 100% rename from probing/__init__.py rename to jiant/proj/main/components/__init__.py diff --git a/jiant/proj/main/components/container_setup.py b/jiant/proj/main/components/container_setup.py new file mode 100644 index 000000000..c4a92de26 --- /dev/null +++ b/jiant/proj/main/components/container_setup.py @@ -0,0 +1,247 @@ +from dataclasses import dataclass +from typing import Dict, List, Optional + + +import jiant.proj.main.components.task_sampler as jiant_task_sampler +import jiant.shared.caching as caching +import jiant.tasks as tasks +import jiant.utils.python.io as py_io +from jiant.utils.python.datastructures import ExtendedDataClassMixin + + +@dataclass +class TaskSpecificConfig(ExtendedDataClassMixin): + train_batch_size: int + eval_batch_size: int + gradient_accumulation_steps: int + eval_subset_num: int + + +@dataclass +class GlobalTrainConfig(ExtendedDataClassMixin): + max_steps: int + warmup_steps: int + + +@dataclass +class TaskmodelsConfig(ExtendedDataClassMixin): + task_to_taskmodel_map: Dict[str, str] + taskmodel_config_map: Optional[Dict[str, Optional[Dict]]] = None + + def get_taskmodel_kwargs(self, taskmodel_name: str) -> Optional[Dict]: + assert taskmodel_name in self.task_to_taskmodel_map.values() + if self.taskmodel_config_map is None: + return None + elif taskmodel_name not in self.taskmodel_config_map: + return None + else: + return self.taskmodel_config_map[taskmodel_name] + + +@dataclass +class TaskRunConfig(ExtendedDataClassMixin): + train_task_list: List[str] + train_val_task_list: List[str] + val_task_list: List[str] + test_task_list: List[str] + + +@dataclass +class JiantTaskContainer: + task_dict: Dict[str, tasks.Task] + task_sampler: jiant_task_sampler.BaseMultiTaskSampler + task_cache_dict: Dict + global_train_config: GlobalTrainConfig + task_specific_configs: Dict[str, TaskSpecificConfig] + taskmodels_config: TaskmodelsConfig + task_run_config: TaskRunConfig + metrics_aggregator: jiant_task_sampler.BaseMetricAggregator + + +def create_task_dict(task_config_dict: dict, verbose: bool = True) -> Dict[str, tasks.Task]: + """Make map of task name to task instances from map of task name to task config file paths. + + Args: + task_config_dict (Dict): map from task name to task config filepath. + verbose (bool): True to print task config info. + + Returns: + Dict mapping from task name to task instance. + + """ + task_dict = { + task_name: tasks.create_task_from_config_path(config_path=task_config_path, verbose=False) + for task_name, task_config_path in task_config_dict.items() + } + if verbose: + print("Creating Tasks:") + for task_name, task_config_path in task_config_dict.items(): + task_class = task_dict[task_name].__class__.__name__ + print(f" {task_name} ({task_class}): {task_config_path}") + return task_dict + + +def create_task_cache_dict(task_cache_config_dict: Dict) -> Dict: + """Takes a map of task cache configs, and returns map of instantiated task data cache objects. + + Notes: + This function assumes that data is divided and stored according to phase where phase takes + a value of train, val, val_labels, or test. + + Args: + task_cache_config_dict (Dict[str, Dict[str, str]]): maps of task names to cache file dirs. + + Returns: + Dict[str, Dict[str, ChunkedFilesDataCache]] mappings from task name to task cache objects. + + """ + task_cache_dict = {} + for task_name, task_cache_config in task_cache_config_dict.items(): + single_task_cache_dict = {} + for phase in ["train", "val", "val_labels", "test"]: + if phase in task_cache_config: + single_task_cache_dict[phase] = caching.ChunkedFilesDataCache( + task_cache_config[phase], + ) + task_cache_dict[task_name] = single_task_cache_dict + return task_cache_dict + + +def get_num_train_examples(task_cache_dict: Dict, train_task_list=None) -> Dict[str, int]: + """Count training examples for tasks. + + Args: + task_cache_dict: nested maps from task name to phases, and from phase to task cache object. + train_task_list (List): list of task names for which to count training examples. + + Notes: + If get_num_train_examples() is called without providing train_task_list, training examples + for all tasks in task_cache_dict are counted by get_num_train_examples(). + + Returns: + Dict[str, int] mapping task names to the count of training examples for that task. + + """ + num_train_examples_dict = {} + if train_task_list is None: + train_task_list = list(task_cache_dict) + for task_name in train_task_list: + single_task_cache_dict = task_cache_dict[task_name] + if "train" in single_task_cache_dict: + num_train_examples_dict[task_name] = len(single_task_cache_dict["train"]) + else: + num_train_examples_dict[task_name] = 0 + return num_train_examples_dict + + +def create_task_specific_configs(task_specific_configs_dict) -> Dict[str, TaskSpecificConfig]: + """Takes task-specific configs, returns them as TaskSpecificConfig(s). + + Args: + task_specific_configs_dict: map task name to map of task-specific config name to value. + + Raises: + TypeError if task-specific config is not either a dict or a TaskSpecificConfig object. + + Returns: + Dict[str, TaskSpecificConfig] map of task name to task-specific configs. + + """ + task_specific_configs = {} + for k, v in task_specific_configs_dict.items(): + if isinstance(v, dict): + v = TaskSpecificConfig.from_dict(v) + elif isinstance(v, TaskSpecificConfig): + pass + else: + raise TypeError(type(v)) + task_specific_configs[k] = v + return task_specific_configs + + +def create_jiant_task_container( + task_config_path_dict: Dict, + task_cache_config_dict: Dict, + sampler_config: Dict, + global_train_config: Dict, + task_specific_configs_dict: Dict, + metric_aggregator_config: Dict, + taskmodels_config: Dict, + task_run_config: Dict, + verbose: bool = True, +) -> JiantTaskContainer: + """Read and interpret config files, initialize configuration objects, return JiantTaskContainer. + + Args: + task_config_path_dict (Dict[str, str]): map of task names to task config files. + task_cache_config_dict (Dict[str, str]): map of task names to cache file dirs. + sampler_config (Dict): map containing sample config options, e.g., uniform task sampling. + global_train_config (Dict): map of training configs shared by all tasks (e.g., max_steps). + task_specific_configs_dict (Dict): map of maps mapping task names to task-specific options. + metric_aggregator_config (Dict): map containing task metric aggregation options. + taskmodels_config: maps mapping from tasks to models, and specifying task-model configs. + task_run_config: config determining which tasks are used in which phase (e.g., train). + verbose: True to print task info. + + Returns: + JiantTaskContainer carrying components configured and set up pre-runner. + + """ + task_dict = create_task_dict(task_config_dict=task_config_path_dict, verbose=verbose) + task_cache_dict = create_task_cache_dict(task_cache_config_dict=task_cache_config_dict) + global_train_config = GlobalTrainConfig.from_dict(global_train_config) + task_specific_config = create_task_specific_configs( + task_specific_configs_dict=task_specific_configs_dict, + ) + taskmodels_config = TaskmodelsConfig.from_dict(taskmodels_config) + task_run_config = TaskRunConfig.from_dict(task_run_config) + + num_train_examples_dict = get_num_train_examples( + task_cache_dict=task_cache_dict, train_task_list=task_run_config.train_task_list, + ) + task_sampler = jiant_task_sampler.create_task_sampler( + sampler_config=sampler_config, + # task sampler samples only from the training tasks + task_dict={ + task_name: task_dict[task_name] for task_name in task_run_config.train_task_list + }, + task_to_num_examples_dict=num_train_examples_dict, + ) + metric_aggregator = jiant_task_sampler.create_metric_aggregator( + metric_aggregator_config=metric_aggregator_config, + ) + return JiantTaskContainer( + task_dict=task_dict, + task_sampler=task_sampler, + global_train_config=global_train_config, + task_cache_dict=task_cache_dict, + task_specific_configs=task_specific_config, + taskmodels_config=taskmodels_config, + task_run_config=task_run_config, + metrics_aggregator=metric_aggregator, + ) + + +def create_jiant_task_container_from_dict( + jiant_task_container_config_dict: Dict, verbose: bool = True +) -> JiantTaskContainer: + return create_jiant_task_container( + task_config_path_dict=jiant_task_container_config_dict["task_config_path_dict"], + task_cache_config_dict=jiant_task_container_config_dict["task_cache_config_dict"], + sampler_config=jiant_task_container_config_dict["sampler_config"], + global_train_config=jiant_task_container_config_dict["global_train_config"], + task_specific_configs_dict=jiant_task_container_config_dict["task_specific_configs_dict"], + taskmodels_config=jiant_task_container_config_dict["taskmodels_config"], + task_run_config=jiant_task_container_config_dict["task_run_config"], + metric_aggregator_config=jiant_task_container_config_dict["metric_aggregator_config"], + verbose=verbose, + ) + + +def create_jiant_task_container_from_json( + jiant_task_container_config_path: str, verbose: bool = True +) -> JiantTaskContainer: + return create_jiant_task_container_from_dict( + jiant_task_container_config_dict=py_io.read_json(jiant_task_container_config_path), + verbose=verbose, + ) diff --git a/jiant/proj/main/components/evaluate.py b/jiant/proj/main/components/evaluate.py new file mode 100644 index 000000000..209a497d1 --- /dev/null +++ b/jiant/proj/main/components/evaluate.py @@ -0,0 +1,38 @@ +import json +import os + +import torch + +import jiant.utils.python.io as py_io +import jiant.proj.main.components.task_sampler as jiant_task_sampler + + +def write_val_results(val_results_dict, metrics_aggregator, output_dir, verbose=True): + full_results_to_write = { + "aggregated": jiant_task_sampler.compute_aggregate_major_metrics_from_results_dict( + metrics_aggregator=metrics_aggregator, results_dict=val_results_dict, + ), + } + for task_name, task_results in val_results_dict.items(): + task_results_to_write = {} + if "loss" in task_results: + task_results_to_write["loss"] = task_results["loss"] + if "metrics" in task_results: + task_results_to_write["metrics"] = task_results["metrics"].to_dict() + full_results_to_write[task_name] = task_results_to_write + + metrics_str = json.dumps(full_results_to_write, indent=2) + if verbose: + print(metrics_str) + + py_io.write_json(data=full_results_to_write, path=os.path.join(output_dir, "val_metrics.json")) + + +def write_preds(eval_results_dict, path): + preds_dict = {} + for task_name, task_results_dict in eval_results_dict.items(): + preds_dict[task_name] = { + "preds": task_results_dict["preds"], + "guids": task_results_dict["accumulator"].get_guids(), + } + torch.save(preds_dict, path) diff --git a/jiant/proj/main/components/outputs.py b/jiant/proj/main/components/outputs.py new file mode 100644 index 000000000..5061bbba3 --- /dev/null +++ b/jiant/proj/main/components/outputs.py @@ -0,0 +1,41 @@ +from dataclasses import dataclass +from typing import Any, Dict + +import torch + +from jiant.utils.python.datastructures import ExtendedDataClassMixin + + +class BaseModelOutput(ExtendedDataClassMixin): + pass + + +@dataclass +class LogitsOutput(BaseModelOutput): + logits: torch.Tensor + other: Any = None + + +@dataclass +class LogitsAndLossOutput(BaseModelOutput): + logits: torch.Tensor + loss: torch.Tensor + other: Any = None + + +@dataclass +class EmbeddingOutput(BaseModelOutput): + embedding: torch.Tensor + other: Any = None + + +def construct_output_from_dict(struct_dict: Dict): + keys = sorted(list(struct_dict.keys())) + if keys == ["logits", "other"]: + return LogitsOutput.from_dict(struct_dict) + elif keys == ["logits", "loss", "other"]: + return LogitsAndLossOutput.from_dict(struct_dict) + elif keys == ["embedding", "other"]: + return EmbeddingOutput.from_dict(struct_dict) + else: + raise ValueError() diff --git a/jiant/proj/main/components/task_sampler.py b/jiant/proj/main/components/task_sampler.py new file mode 100644 index 000000000..a16676d9b --- /dev/null +++ b/jiant/proj/main/components/task_sampler.py @@ -0,0 +1,259 @@ +import abc +import numexpr +import numpy as np + +from typing import Union, Optional, Dict + + +class BaseMultiTaskSampler(metaclass=abc.ABCMeta): + def __init__(self, task_dict: dict, rng: Union[int, np.random.RandomState, None]): + self.task_dict = task_dict + if isinstance(rng, int) or rng is None: + rng = np.random.RandomState(rng) + self.rng = rng + + def pop(self): + raise NotImplementedError() + + def iter(self): + yield self.pop() + + +class UniformMultiTaskSampler(BaseMultiTaskSampler): + def pop(self): + task_name = self.rng.choice(list(self.task_dict)) + return task_name, self.task_dict[task_name] + + +class ProportionalMultiTaskSampler(BaseMultiTaskSampler): + def __init__( + self, + task_dict: dict, + rng: Union[int, np.random.RandomState], + task_to_num_examples_dict: dict, + ): + super().__init__(task_dict=task_dict, rng=rng) + assert task_dict.keys() == task_to_num_examples_dict.keys() + self.task_to_examples_dict = task_to_num_examples_dict + self.task_names = list(task_to_num_examples_dict.keys()) + self.task_num_examples = np.array([task_to_num_examples_dict[k] for k in self.task_names]) + self.task_p = self.task_num_examples / self.task_num_examples.sum() + + def pop(self): + task_name = self.rng.choice(self.task_names, p=self.task_p) + return task_name, self.task_dict[task_name] + + +class SpecifiedProbMultiTaskSampler(BaseMultiTaskSampler): + def __init__( + self, + task_dict: dict, + rng: Union[int, np.random.RandomState], + task_to_unweighted_probs: dict, + ): + super().__init__(task_dict=task_dict, rng=rng) + assert task_dict.keys() == task_to_unweighted_probs.keys() + self.task_to_unweighted_probs = task_to_unweighted_probs + self.task_names = list(task_to_unweighted_probs.keys()) + self.unweighted_probs_arr = np.array([task_to_unweighted_probs[k] for k in self.task_names]) + self.task_p = self.unweighted_probs_arr / self.unweighted_probs_arr.sum() + + def pop(self): + task_name = self.rng.choice(self.task_names, p=self.task_p) + return task_name, self.task_dict[task_name] + + +class TemperatureMultiTaskSampler(BaseMultiTaskSampler): + def __init__( + self, + task_dict: dict, + rng: Union[int, np.random.RandomState], + task_to_num_examples_dict: dict, + temperature: float, + examples_cap: Optional[int], + ): + super().__init__(task_dict=task_dict, rng=rng) + assert task_dict.keys() == task_to_num_examples_dict.keys() + self.task_to_num_examples_dict = task_to_num_examples_dict + self.temperature = temperature + self.examples_cap = examples_cap + self.task_names = list(task_to_num_examples_dict.keys()) + self.task_num_examples = np.array([task_to_num_examples_dict[k] for k in self.task_names]) + raw_n = self.task_num_examples.clip(max=examples_cap) ** (1 / self.temperature) + self.task_p = raw_n / raw_n.sum() + + def pop(self): + task_name = self.rng.choice(self.task_names, p=self.task_p) + return task_name, self.task_dict[task_name] + + +class TimeDependentProbMultiTaskSampler(BaseMultiTaskSampler): + """Multi-task Sampler with different task sampling probabilities over time + + We describe the individual unnormalized probabilities using numexpr expressions, + using t as the variable, e.g.: + * 1 (constant) + * 2 * t (linear) + * 1/sqrt(t) (inverse square-root) + + These are computed for all tasks for each time step, and then normalized to sum to 1. + + Attributes: + task_dict: Dictionary of tasks + rng: Random seed, or NumPy RandomState for sampling + task_to_unnormalized_prob_funcs_dict: map from task names to strings, which are + numexpr expressions + max_steps: Maximum number of steps allows (in the case where some functions + are not valid after a given t. + """ + + def __init__( + self, + task_dict: dict, + rng: Union[int, np.random.RandomState], + task_to_unnormalized_prob_funcs_dict: dict, + max_steps: Optional[int] = None, + ): + super().__init__(task_dict=task_dict, rng=rng) + assert task_dict.keys() == task_to_unnormalized_prob_funcs_dict.keys() + self.task_to_unnormalized_prob_funcs_dict = task_to_unnormalized_prob_funcs_dict + self.max_steps = max_steps + + self.task_names = list(task_to_unnormalized_prob_funcs_dict.keys()) + self.steps = 0 + + def pop(self): + if self.max_steps is not None and self.steps >= self.max_steps: + raise IndexError(f"steps ({self.steps}) > max_steps ({self.max_steps})") + task_name = self.rng.choice(self.task_names, p=self.get_task_p(self.steps)) + self.steps += 1 + return task_name, self.task_dict[task_name] + + def get_task_p(self, steps=None) -> np.ndarray: + p_ls = np.empty(len(self.task_names)) + + # t is the variable in the numexpr expression + t = steps if steps is not None else self.steps + + for i, task_name in enumerate(self.task_names): + p_ls[i] = numexpr.evaluate( + self.task_to_unnormalized_prob_funcs_dict[task_name], local_dict={"t": t}, + ) + p_ls /= p_ls.sum() + return p_ls + + def reset_counter(self): + self.steps = 0 + + +def create_task_sampler( + sampler_config: dict, task_dict: dict, task_to_num_examples_dict: dict, rng=None +) -> BaseMultiTaskSampler: + """Perform basic config validation, then instantiate and return the specified multitask sampler. + + Args: + sampler_config (Dict): map containing sample config options. + task_dict (Dict[str, Task]): map from task name to task instance. + task_to_num_examples_dict (Dict[str, int]): map task names to counts of training examples. + rng (Union[int, np.random.RandomState, None]): random state to seed sampler. + + Raises: + KeyError if invalid sampler type argument is provided in the sampler config. + + Returns: + Subclass of BaseMultiTaskSampler. + + """ + sampler_type = sampler_config["sampler_type"] + if sampler_type == "UniformMultiTaskSampler": + assert len(sampler_config) == 1 + return UniformMultiTaskSampler(task_dict=task_dict, rng=rng) + elif sampler_type == "ProportionalMultiTaskSampler": + assert len(sampler_config) == 1 + return ProportionalMultiTaskSampler( + task_dict=task_dict, rng=rng, task_to_num_examples_dict=task_to_num_examples_dict, + ) + elif sampler_type == "SpecifiedProbMultiTaskSampler": + assert len(sampler_config) == 2 + return SpecifiedProbMultiTaskSampler( + task_dict=task_dict, + rng=rng, + task_to_unweighted_probs=sampler_config["task_to_unweighted_probs"], + ) + elif sampler_type == "TemperatureMultiTaskSampler": + assert len(sampler_config) == 3 + return TemperatureMultiTaskSampler( + task_dict=task_dict, + rng=rng, + task_to_num_examples_dict=task_to_num_examples_dict, + temperature=sampler_config["temperature"], + examples_cap=sampler_config["examples_cap"], + ) + elif sampler_type == "TimeDependentProbMultiTaskSampler": + assert len(sampler_config) == 3 + return TimeDependentProbMultiTaskSampler( + task_dict=task_dict, + rng=rng, + task_to_unnormalized_prob_funcs_dict=sampler_config[ + "task_to_unnormalized_prob_funcs_dict" + ], + max_steps=sampler_config["max_steps"], + ) + else: + raise KeyError(sampler_type) + + +class BaseMetricAggregator(metaclass=abc.ABCMeta): + def aggregate(self, major_metrics_dict: Dict[str, float]): + raise NotImplementedError() + + +class EqualMetricAggregator(BaseMetricAggregator): + def aggregate(self, major_metrics_dict: Dict[str, float]): + return np.mean([x for x in major_metrics_dict.values()]) + + +class WeightedMetricAggregator(BaseMetricAggregator): + def __init__(self, weights_dict: Dict[str, float]): + self.weights_dict = weights_dict + self.total_weights = sum([x for x in weights_dict.values()]) + + def aggregate(self, major_metrics_dict: Dict[str, float]): + return ( + np.sum( + [x * self.weights_dict[task_name] for task_name, x in major_metrics_dict.items()] + ) + / self.total_weights + ) + + +def create_metric_aggregator(metric_aggregator_config: Dict) -> BaseMetricAggregator: + """Perform basic config validation, then instantiate and return the specified metric aggregator. + + Args: + metric_aggregator_config (Dict): map containing metric aggregation options. + + Returns: + Subclass of BaseMetricAggregator. + + """ + metric_aggregator_type = metric_aggregator_config["metric_aggregator_type"] + if metric_aggregator_type == "EqualMetricAggregator": + assert len(metric_aggregator_config) == 1 + return EqualMetricAggregator() + elif metric_aggregator_type == "WeightedMetricAggregator": + assert len(metric_aggregator_config) == 2 + return WeightedMetricAggregator(weights_dict=metric_aggregator_config["weights_dict"]) + else: + raise KeyError(metric_aggregator_type) + + +def compute_aggregate_major_metrics_from_results_dict(metrics_aggregator, results_dict): + major_metrics_dict = { + task_name: results["metrics"].major for task_name, results in results_dict.items() + } + return metrics_aggregator.aggregate(major_metrics_dict=major_metrics_dict) + + +def get_metrics_dict_from_results_dict(results_dict): + return {task_name: results["metrics"].to_dict() for task_name, results in results_dict.items()} diff --git a/jiant/proj/main/components/write_configs.py b/jiant/proj/main/components/write_configs.py new file mode 100644 index 000000000..a193e3a5b --- /dev/null +++ b/jiant/proj/main/components/write_configs.py @@ -0,0 +1,32 @@ +import os + +import jiant.utils.python.io as py_io + + +def write_configs(config_dict, base_path): + os.makedirs(base_path, exist_ok=True) + config_keys = [ + "task_config_path_dict", + "task_cache_config_dict", + "sampler_config", + "global_train_config", + "task_specific_configs_dict", + "metric_aggregator_config", + ] + for path in config_dict["task_config_path_dict"].values(): + assert os.path.exists(path) + for path_dict in config_dict["task_cache_config_dict"].values(): + for path in path_dict.values(): + assert os.path.exists(path) + for config_key in config_keys: + py_io.write_json( + config_dict[config_key], os.path.join(base_path, f"{config_key}.json"), + ) + py_io.write_json(config_dict, os.path.join(base_path, "full.json")) + py_io.write_json( + { + f"{config_key}_path": os.path.join(base_path, f"{config_key}.json") + for config_key in config_keys + }, + path=os.path.join(base_path, "zz_full.json"), + ) diff --git a/jiant/proj/main/export_model.py b/jiant/proj/main/export_model.py new file mode 100644 index 000000000..ee9ab8bb9 --- /dev/null +++ b/jiant/proj/main/export_model.py @@ -0,0 +1,107 @@ +import os +from typing import Tuple, Type + +import torch +import transformers + +import jiant.utils.python.io as py_io +import jiant.utils.zconf as zconf + + +@zconf.run_config +class RunConfiguration(zconf.RunConfig): + model_type = zconf.attr(type=str) + output_base_path = zconf.attr(type=str) + hf_model_name = zconf.attr(type=str, default=None) + + +def lookup_and_export_model(model_type: str, output_base_path: str, hf_model_name: str = None): + model_class, tokenizer_class = get_model_and_tokenizer_classes(model_type) + export_model( + model_type=model_type, + output_base_path=output_base_path, + model_class=model_class, + tokenizer_class=tokenizer_class, + hf_model_name=hf_model_name, + ) + + +def export_model( + model_type: str, + output_base_path: str, + model_class: Type[transformers.PreTrainedModel], + tokenizer_class: Type[transformers.PreTrainedTokenizer], + hf_model_name: str = None, +): + """Retrieve model and tokenizer from Transformers and save all necessary data + Things saved: + - Model weights + - Model config JSON (corresponding to corresponding Transformers model Config object) + - Tokenizer data + - JSON file pointing to paths for the above + Args: + model_type: Model-type string. See: `get_model_and_tokenizer_classes` + output_base_path: Base path to save output to + model_class: Model class + tokenizer_class: Tokenizer class + hf_model_name: (Optional) hf_model_name from https://huggingface.co/models, + if it differs from model_type + """ + if hf_model_name is None: + hf_model_name = model_type + + tokenizer_fol_path = os.path.join(output_base_path, "tokenizer") + model_fol_path = os.path.join(output_base_path, "model") + os.makedirs(tokenizer_fol_path, exist_ok=True) + os.makedirs(model_fol_path, exist_ok=True) + + model_path = os.path.join(model_fol_path, f"{model_type}.p") + model_config_path = os.path.join(model_fol_path, f"{model_type}.json") + model = model_class.from_pretrained(hf_model_name) + torch.save(model.state_dict(), model_path) + py_io.write_json(model.config.to_dict(), model_config_path) + tokenizer = tokenizer_class.from_pretrained(hf_model_name) + tokenizer.save_pretrained(tokenizer_fol_path) + config = { + "model_type": model_type, + "model_path": model_path, + "model_config_path": model_config_path, + "model_tokenizer_path": tokenizer_fol_path, + } + py_io.write_json(config, os.path.join(output_base_path, f"config.json")) + + +def get_model_and_tokenizer_classes( + model_type: str, +) -> Tuple[Type[transformers.PreTrainedModel], Type[transformers.PreTrainedTokenizer]]: + # We want the chosen model to have all the weights from pretraining (if possible) + class_lookup = { + "bert": (transformers.BertForPreTraining, transformers.BertTokenizer), + "xlm-clm-": (transformers.XLMWithLMHeadModel, transformers.XLMTokenizer), + "roberta": (transformers.RobertaForMaskedLM, transformers.RobertaTokenizer), + "albert": (transformers.AlbertForMaskedLM, transformers.AlbertTokenizer), + "bart": (transformers.BartForConditionalGeneration, transformers.BartTokenizer), + "mbart": (transformers.BartForConditionalGeneration, transformers.MBartTokenizer), + "electra": (transformers.ElectraForPreTraining, transformers.ElectraTokenizer), + } + if model_type.split("-")[0] in class_lookup: + return class_lookup[model_type.split("-")[0]] + elif model_type.startswith("xlm-mlm-") or model_type.startswith("xlm-clm-"): + return transformers.XLMWithLMHeadModel, transformers.XLMTokenizer + elif model_type.startswith("xlm-roberta-"): + return transformers.XLMRobertaForMaskedLM, transformers.XLMRobertaTokenizer + else: + raise KeyError() + + +def main(): + args = RunConfiguration.default_run_cli() + lookup_and_export_model( + model_type=args.model_type, + output_base_path=args.output_base_path, + hf_model_name=args.hf_model_name, + ) + + +if __name__ == "__main__": + main() diff --git a/jiant/proj/main/metarunner.py b/jiant/proj/main/metarunner.py new file mode 100644 index 000000000..154c770cd --- /dev/null +++ b/jiant/proj/main/metarunner.py @@ -0,0 +1,244 @@ +from dataclasses import dataclass +from typing import Dict +import torch.nn as nn + + +import jiant.proj.main.runner as jiant_runner +import jiant.proj.main.components.task_sampler as jiant_task_sampler +from jiant.shared.runner import ( + save_model_with_metadata, + compare_steps_max_steps, +) +from jiant.utils.python.datastructures import ExtendedDataClassMixin +from jiant.utils.python.functional import always_false +from jiant.utils.torch_utils import copy_state_dict, CPU_DEVICE, get_model_for_saving +from jiant.utils.zlog import BaseZLogger, PRINT_LOGGER +from jiant.shared.metarunner import AbstractMetarunner + + +@dataclass +class ValState(ExtendedDataClassMixin): + score: float + metrics: Dict + train_state: jiant_runner.TrainState + + def new(self): + # noinspection PyArgumentList + return self.__class__( + score=self.score, metrics=self.metrics, train_state=self.train_state.new(), + ) + + def to_dict(self): + return { + "score": float(self.score), + "metrics": self.metrics, + "train_state": self.train_state.to_dict(), + } + + +def get_should_early_stop_func(eval_every_steps: int, no_improvements_for_n_evals: int): + assert eval_every_steps != 0 + if no_improvements_for_n_evals == 0: + return always_false + else: + return lambda metarunner: ( + metarunner.train_state.global_steps is not None + and metarunner.best_val_state is not None + and ( + metarunner.best_val_state.train_state.global_steps + - metarunner.train_state.global_steps + ) + / eval_every_steps + > no_improvements_for_n_evals + ) + + +class JiantMetarunner(AbstractMetarunner): + def __init__( + self, + runner: jiant_runner.JiantRunner, + save_every_steps, + eval_every_steps, + save_checkpoint_every_steps, + no_improvements_for_n_evals, + checkpoint_saver, + output_dir, + verbose: bool = True, + save_best_model: bool = True, + load_best_model: bool = True, + log_writer: BaseZLogger = PRINT_LOGGER, + ): + self.runner = runner + self.save_every_steps = save_every_steps + self.eval_every_steps = eval_every_steps + self.save_checkpoint_every_steps = save_checkpoint_every_steps + self.no_improvements_for_n_evals = no_improvements_for_n_evals + self.checkpoint_saver = checkpoint_saver + self.output_dir = output_dir + self.verbose = verbose + self.save_best_model = save_best_model + self.load_best_model = load_best_model + self.log_writer = log_writer + + self.best_val_state = None + self.best_state_dict = None + self.val_state_history = [] + self.train_state = None + self.full_break = False + self.single_use_check = False + self.num_evals_since_improvement = 0 + + self.model = self.runner.model + self.device = self.runner.device + self.global_train_config = self.runner.jiant_task_container.global_train_config + + def begin_training(self): + assert not self.single_use_check + self.single_use_check = True + + def yield_train_step(self): + if self.train_state is None: + # Fresh run + train_iterator = self.runner.run_train_context(verbose=self.verbose) + else: + train_iterator = self.runner.resume_train_context( + train_state=self.train_state, verbose=self.verbose, + ) + for train_state in train_iterator: + self.train_state = train_state + self.inject_at_step() + yield + + def should_save_model(self) -> bool: + if self.save_every_steps == 0: + return False + return (self.train_state.global_steps + 1) % self.save_every_steps == 0 + + def save_model(self): + save_model_with_metadata( + model=self.model, + metadata={}, + output_dir=self.output_dir, + file_name=f"model__{self.train_state.global_steps:09d}", + ) + + def should_save_checkpoint(self) -> bool: + if self.save_checkpoint_every_steps == 0: + return False + return (self.train_state.global_steps + 1) % self.save_checkpoint_every_steps == 0 + + def save_checkpoint(self): + runner_state = self.runner.get_runner_state() + metarunner_state = self.get_state() + print("Saving State") + self.checkpoint_saver.save(runner_state=runner_state, metarunner_state=metarunner_state) + + def should_eval_model(self) -> bool: + if self.eval_every_steps == 0: + return False + return (self.train_state.global_steps + 1) % self.eval_every_steps == 0 + + def eval_model(self): + self.eval_save() + + def should_break_training(self) -> bool: + if compare_steps_max_steps( + step=self.train_state.global_steps, max_steps=self.global_train_config.max_steps + ): + return True + + if self.no_improvements_for_n_evals != 0: + if self.num_evals_since_improvement >= self.no_improvements_for_n_evals: + self.log_writer.write_entry( + "early_stopping", + {"message": "early_stopped", "train_state": self.train_state.to_dict()}, + ) + self.log_writer.flush() + return True + + return False + + def done_training(self): + self.eval_save() + if self.load_best_model and self.best_state_dict is not None: + if self.verbose: + print("Loading Best") + copied_state_dict = copy_state_dict( + state_dict=self.best_state_dict, + target_device=None, # Why was this required? + # target_device=self.device, + ) + if isinstance(self.model, nn.DataParallel): + self.model.module.load_state_dict(copied_state_dict) + else: + self.model.load_state_dict(copied_state_dict) + + def returned_result(self): + return { + "best_val_state": self.best_val_state, + "val_state_history": self.val_state_history, + } + + # ======================== # + + def inject_at_step(self): + pass + + def get_state(self): + return { + "best_val_state": self.best_val_state, + "best_state_dict": self.best_state_dict, + "train_state": self.train_state, + } + + def load_state(self, metarunner_state): + self.best_val_state = metarunner_state["best_val_state"] + self.best_state_dict = metarunner_state["best_state_dict"] + self.train_state = metarunner_state["train_state"] + + def eval_save(self): + self.num_evals_since_improvement += 1 + val_results_dict = self.runner.run_val( + task_name_list=self.runner.jiant_task_container.task_run_config.train_val_task_list, + use_subset=True, + ) + aggregated_major = jiant_task_sampler.compute_aggregate_major_metrics_from_results_dict( + metrics_aggregator=self.runner.jiant_task_container.metrics_aggregator, + results_dict=val_results_dict, + ) + val_metrics_dict = jiant_task_sampler.get_metrics_dict_from_results_dict( + results_dict=val_results_dict, + ) + val_state = ValState( + score=float(aggregated_major), + metrics=val_metrics_dict, + train_state=self.train_state.new(), + ) + self.log_writer.write_entry("train_val", val_state.to_dict()) + if self.best_val_state is None or val_state.score > self.best_val_state.score: + self.best_val_state = val_state.new() + self.log_writer.write_entry("train_val_best", self.best_val_state.to_dict()) + if self.save_best_model: + save_model_with_metadata( + model=self.model, + metadata={ + "val_state": self.best_val_state.to_dict(), + "val_metrics": val_metrics_dict, + }, + output_dir=self.output_dir, + file_name="best_model", + ) + del self.best_state_dict + self.best_state_dict = copy_state_dict( + state_dict=get_model_for_saving(self.model).state_dict(), target_device=CPU_DEVICE, + ) + self.num_evals_since_improvement = 0 + self.log_writer.write_entry( + "early_stopping", + { + "num_evals_since_improvement": self.num_evals_since_improvement, + "train_state": self.train_state.to_dict(), + }, + ) + self.log_writer.flush() + self.val_state_history.append(val_state) diff --git a/probing/data/__init__.py b/jiant/proj/main/modeling/__init__.py similarity index 100% rename from probing/data/__init__.py rename to jiant/proj/main/modeling/__init__.py diff --git a/jiant/proj/main/modeling/heads.py b/jiant/proj/main/modeling/heads.py new file mode 100644 index 000000000..38b637c99 --- /dev/null +++ b/jiant/proj/main/modeling/heads.py @@ -0,0 +1,207 @@ +import abc + +import torch +import torch.nn as nn + +import transformers +from jiant.ext.allennlp import SelfAttentiveSpanExtractor + +""" +In HuggingFace/others, these heads differ slightly across different encoder models. +We're going to abstract away from that and just choose one implementation. +""" + + +class BaseHead(nn.Module, metaclass=abc.ABCMeta): + pass + + +class ClassificationHead(BaseHead): + def __init__(self, hidden_size, hidden_dropout_prob, num_labels): + """From RobertaClassificationHead""" + super().__init__() + self.dense = nn.Linear(hidden_size, hidden_size) + self.dropout = nn.Dropout(hidden_dropout_prob) + self.out_proj = nn.Linear(hidden_size, num_labels) + self.num_labels = num_labels + + def forward(self, pooled): + x = self.dropout(pooled) + x = self.dense(x) + x = torch.tanh(x) + x = self.dropout(x) + logits = self.out_proj(x) + return logits + + +class RegressionHead(BaseHead): + def __init__(self, hidden_size, hidden_dropout_prob): + """From RobertaClassificationHead""" + super().__init__() + self.dense = nn.Linear(hidden_size, hidden_size) + self.dropout = nn.Dropout(hidden_dropout_prob) + self.out_proj = nn.Linear(hidden_size, 1) + + def forward(self, pooled): + x = self.dropout(pooled) + x = self.dense(x) + x = torch.tanh(x) + x = self.dropout(x) + scores = self.out_proj(x) + return scores + + +class SpanComparisonHead(BaseHead): + def __init__(self, hidden_size, hidden_dropout_prob, num_spans, num_labels): + """From RobertaForSpanComparisonClassification""" + super().__init__() + self.num_spans = num_spans + self.num_labels = num_labels + self.hidden_size = hidden_size + self.dropout = nn.Dropout(hidden_dropout_prob) + self.span_attention_extractor = SelfAttentiveSpanExtractor(hidden_size) + self.classifier = nn.Linear(hidden_size * self.num_spans, self.num_labels) + + def forward(self, unpooled, spans): + span_embeddings = self.span_attention_extractor(unpooled, spans) + span_embeddings = span_embeddings.view(-1, self.num_spans * self.hidden_size) + span_embeddings = self.dropout(span_embeddings) + logits = self.classifier(span_embeddings) + return logits + + +class TokenClassificationHead(BaseHead): + def __init__(self, hidden_size, num_labels, hidden_dropout_prob): + """From RobertaForTokenClassification""" + super().__init__() + self.num_labels = num_labels + self.dropout = nn.Dropout(hidden_dropout_prob) + self.classifier = nn.Linear(hidden_size, num_labels) + + def forward(self, unpooled): + unpooled = self.dropout(unpooled) + logits = self.classifier(unpooled) + return logits + + +class QAHead(BaseHead): + def __init__(self, hidden_size): + """From RobertaForQuestionAnswering""" + super().__init__() + self.qa_outputs = nn.Linear(hidden_size, 2) + + def forward(self, unpooled): + logits = self.qa_outputs(unpooled) + # bs x seq_len x 2 + logits = logits.permute(0, 2, 1) + # bs x 2 x seq_len x 1 + return logits + + +class BaseMLMHead(BaseHead, metaclass=abc.ABCMeta): + pass + + +class BertMLMHead(BaseMLMHead): + """From BertOnlyMLMHead, BertLMPredictionHead, BertPredictionHeadTransform""" + + def __init__(self, hidden_size, vocab_size, layer_norm_eps=1e-12, hidden_act="gelu"): + super().__init__() + self.dense = nn.Linear(hidden_size, hidden_size) + self.transform_act_fn = transformers.modeling_bert.ACT2FN[hidden_act] + self.LayerNorm = transformers.modeling_bert.BertLayerNorm(hidden_size, eps=layer_norm_eps) + + self.decoder = nn.Linear(hidden_size, vocab_size, bias=False) + self.bias = nn.Parameter(torch.zeros(vocab_size), requires_grad=True) + + # Need a link between the two variables so that the bias is correctly resized with + # `resize_token_embeddings` + self.decoder.bias = self.bias + + def forward(self, unpooled): + hidden_states = self.dense(unpooled) + hidden_states = self.transform_act_fn(hidden_states) + hidden_states = self.LayerNorm(hidden_states) + logits = self.decoder(hidden_states) + self.bias + return logits + + +class RobertaMLMHead(BaseMLMHead): + """From RobertaLMHead""" + + def __init__(self, hidden_size, vocab_size, layer_norm_eps=1e-12): + super().__init__() + self.dense = nn.Linear(hidden_size, hidden_size) + self.layer_norm = transformers.modeling_bert.BertLayerNorm(hidden_size, eps=layer_norm_eps) + + self.decoder = nn.Linear(hidden_size, vocab_size, bias=False) + self.bias = nn.Parameter(torch.zeros(vocab_size), requires_grad=True) + + # Need a link between the two variables so that the bias is correctly resized with + # `resize_token_embeddings` + self.decoder.bias = self.bias + + def forward(self, unpooled): + x = self.dense(unpooled) + x = transformers.modeling_bert.gelu(x) + x = self.layer_norm(x) + + # project back to size of vocabulary with bias + logits = self.decoder(x) + self.bias + return logits + + +class AlbertMLMHead(nn.Module): + """From AlbertMLMHead""" + + def __init__(self, hidden_size, embedding_size, vocab_size, hidden_act="gelu"): + super().__init__() + + self.LayerNorm = nn.LayerNorm(embedding_size) + self.bias = nn.Parameter(torch.zeros(vocab_size), requires_grad=True) + self.dense = nn.Linear(hidden_size, embedding_size) + self.decoder = nn.Linear(embedding_size, vocab_size) + self.activation = transformers.modeling_bert.ACT2FN[hidden_act] + + # Need a link between the two variables so that the bias is correctly resized with + # `resize_token_embeddings` + self.decoder.bias = self.bias + + def forward(self, unpooled): + hidden_states = self.dense(unpooled) + hidden_states = self.activation(hidden_states) + hidden_states = self.LayerNorm(hidden_states) + hidden_states = self.decoder(hidden_states) + + logits = hidden_states + self.bias + return logits + + +class AbstractPoolerHead(nn.Module): + pass + + +class MeanPoolerHead(AbstractPoolerHead): + def __init__(self): + super().__init__() + + # noinspection PyMethodMayBeStatic + def forward(self, unpooled, input_mask): + # [batch_size, length, hidden_dim] + assert len(unpooled.shape) == 3 + # [batch_size, length] + assert len(input_mask.shape) == 2 + lengths = input_mask.sum(dim=1).float() + summed = (unpooled * input_mask.float().unsqueeze(2)).sum(1) + return summed / lengths.unsqueeze(1) + + +class FirstPoolerHead(AbstractPoolerHead): + def __init__(self): + super().__init__() + + # noinspection PyMethodMayBeStatic + def forward(self, unpooled): + # [batch_size, length, hidden_dim] + assert len(unpooled.shape) == 3 + return unpooled[:, 0] diff --git a/jiant/proj/main/modeling/model_setup.py b/jiant/proj/main/modeling/model_setup.py new file mode 100644 index 000000000..faefa939d --- /dev/null +++ b/jiant/proj/main/modeling/model_setup.py @@ -0,0 +1,512 @@ +from dataclasses import dataclass +from typing import Any, Dict, List, Optional + +import torch +import torch.nn as nn +import transformers + + +import jiant.proj.main.components.container_setup as container_setup +import jiant.proj.main.modeling.primary as primary +import jiant.proj.main.modeling.taskmodels as taskmodels +import jiant.proj.main.modeling.heads as heads +import jiant.shared.model_setup as model_setup +import jiant.utils.python.strings as strings +from jiant.shared.model_setup import ModelArchitectures +from jiant.tasks import Task, TaskTypes + + +def setup_jiant_model( + model_type: str, + model_config_path: str, + tokenizer_path: str, + task_dict: Dict[str, Task], + taskmodels_config: container_setup.TaskmodelsConfig, +): + """Sets up tokenizer, encoder, and task models, and instantiates and returns a JiantModel. + + Args: + model_type (str): model shortcut name. + model_config_path (str): Path to the JSON file containing the configuration parameters. + tokenizer_path (str): path to tokenizer directory. + task_dict (Dict[str, tasks.Task]): map from task name to task instance. + taskmodels_config: maps mapping from tasks to models, and specifying task-model configs. + + Returns: + JiantModel nn.Module. + + """ + model_arch = ModelArchitectures.from_model_type(model_type) + transformers_class_spec = TRANSFORMERS_CLASS_SPEC_DICT[model_arch] + tokenizer = model_setup.get_tokenizer(model_type=model_type, tokenizer_path=tokenizer_path) + ancestor_model = get_ancestor_model( + transformers_class_spec=transformers_class_spec, model_config_path=model_config_path, + ) + encoder = get_encoder(model_arch=model_arch, ancestor_model=ancestor_model) + taskmodels_dict = { + taskmodel_name: create_taskmodel( + task=task_dict[task_name_list[0]], # Take the first task + model_arch=model_arch, + encoder=encoder, + taskmodel_kwargs=taskmodels_config.get_taskmodel_kwargs(taskmodel_name), + ) + for taskmodel_name, task_name_list in get_taskmodel_and_task_names( + taskmodels_config.task_to_taskmodel_map + ).items() + } + return primary.JiantModel( + task_dict=task_dict, + encoder=encoder, + taskmodels_dict=taskmodels_dict, + task_to_taskmodel_map=taskmodels_config.task_to_taskmodel_map, + tokenizer=tokenizer, + ) + + +def delegate_load_from_path(jiant_model: primary.JiantModel, weights_path: str, load_mode: str): + """Load weights dict from file and load weights according to specified loading mode. + + Args: + jiant_model (JiantModel): jiant model (encoder and task models are core components). + weights_path (str): filepath to weights object saved with torch.save(). + load_mode (str): TODO + + Returns: + TODO: return behavior is not consistent between load_mode options, clarify as needed here. + + """ + weights_dict = torch.load(weights_path) + return delegate_load(jiant_model=jiant_model, weights_dict=weights_dict, load_mode=load_mode) + + +def delegate_load(jiant_model, weights_dict: dict, load_mode: str): + """Load weights dict into JiantModel according to specified loading mode. + + Args: + jiant_model (JiantModel): jiant model (encoder and task models are core components). + weights_dict (Dict): model weights. + load_mode: TODO + + Returns: + TODO: return behavior is not consistent between load_mode options, clarify as needed here. + + """ + if load_mode == "from_transformers": + return load_encoder_from_transformers_weights( + encoder=jiant_model.encoder, weights_dict=weights_dict, + ) + elif load_mode == "from_transformers_with_mlm": + remainder = load_encoder_from_transformers_weights( + encoder=jiant_model.encoder, weights_dict=weights_dict, return_remainder=True, + ) + load_lm_heads_from_transformers_weights( + jiant_model=jiant_model, weights_dict=remainder, + ) + return + elif load_mode == "all": + jiant_model.load_state_dict(weights_dict) + elif load_mode == "partial_weights": + return load_partial_heads( + jiant_model=jiant_model, weights_dict=weights_dict, allow_missing_head_weights=True, + ) + elif load_mode == "partial_heads": + return load_partial_heads( + jiant_model=jiant_model, weights_dict=weights_dict, allow_missing_head_model=True, + ) + elif load_mode == "partial": + return load_partial_heads( + jiant_model=jiant_model, + weights_dict=weights_dict, + allow_missing_head_weights=True, + allow_missing_head_model=True, + ) + else: + raise KeyError(load_mode) + + +def load_encoder_from_transformers_weights( + encoder: nn.Module, weights_dict: dict, return_remainder=False +): + """Find encoder weights in weights dict, load them into encoder, return any remaining weights. + + TODO: clarify how we know the encoder weights will be prefixed by transformer name. + + Args: + encoder (PreTrainedModel): Transformer w/o heads (embedding layer + self-attention layer). + weights_dict (Dict): model weights. + return_remainder (bool): If True, return any leftover weights. + + Returns: + Dict containing any leftover weights. + + """ + remainder_weights_dict = {} + load_weights_dict = {} + model_arch = ModelArchitectures.from_encoder(encoder=encoder) + encoder_prefix = MODEL_PREFIX[model_arch] + "." + # Encoder + for k, v in weights_dict.items(): + if k.startswith(encoder_prefix): + load_weights_dict[strings.remove_prefix(k, encoder_prefix)] = v + else: + remainder_weights_dict[k] = v + encoder.load_state_dict(load_weights_dict) + if return_remainder: + return remainder_weights_dict + + +def load_lm_heads_from_transformers_weights(jiant_model, weights_dict): + model_arch = get_model_arch_from_jiant_model(jiant_model=jiant_model) + if model_arch == ModelArchitectures.BERT: + mlm_weights_map = { + "bias": "cls.predictions.bias", + "dense.weight": "cls.predictions.transform.dense.weight", + "dense.bias": "cls.predictions.transform.dense.bias", + "LayerNorm.weight": "cls.predictions.transform.LayerNorm.weight", + "LayerNorm.bias": "cls.predictions.transform.LayerNorm.bias", + "decoder.weight": "cls.predictions.decoder.weight", + "decoder.bias": "cls.predictions.bias", # <-- linked directly to bias + } + mlm_weights_dict = {new_k: weights_dict[old_k] for new_k, old_k in mlm_weights_map.items()} + elif model_arch in (ModelArchitectures.ROBERTA, ModelArchitectures.XLM_ROBERTA): + mlm_weights_dict = { + strings.remove_prefix(k, "lm_head."): v for k, v in weights_dict.items() + } + mlm_weights_dict["decoder.bias"] = mlm_weights_dict["bias"] + elif model_arch == ModelArchitectures.ALBERT: + mlm_weights_dict = { + strings.remove_prefix(k, "predictions."): v for k, v in weights_dict.items() + } + else: + raise KeyError(model_arch) + missed = set() + for taskmodel_name, taskmodel in jiant_model.taskmodels_dict.items(): + if not isinstance(taskmodel, taskmodels.MLMModel): + continue + mismatch = taskmodel.mlm_head.load_state_dict(mlm_weights_dict) + assert not mismatch.missing_keys + missed.update(mismatch.unexpected_keys) + taskmodel.mlm_head.decoder.weight = jiant_model.encoder.embeddings.word_embeddings.weight + return list(missed) + + +def load_partial_heads( + jiant_model, weights_dict, allow_missing_head_weights=False, allow_missing_head_model=False +): + """Loads model weights and returns lists of missing head weights or missing heads (if any). + + Args: + jiant_model (JiantModel): jiant model (encoder and task models are core components). + weights_dict (Dict): model weights. + allow_missing_head_weights (bool): If False, throw exception if there are missing keys. + allow_missing_head_model (bool): If False, throw exception if there are unexpected keys. + + Returns: + Dict[str, List] containing lists of missing head weights or missing heads if any. + + """ + mismatch = jiant_model.load_state_dict(weights_dict, strict=False) + result = {} + if mismatch.missing_keys: + assert allow_missing_head_weights + missing_head_weights = set() + for k in mismatch.missing_keys: + missing_head_weights.add(k.split(".")[1]) + result["missing_head_weights"] = list(missing_head_weights) + if mismatch.unexpected_keys: + assert allow_missing_head_model + missing_heads_model = set() + for k in mismatch.unexpected_keys: + missing_heads_model.add(k.split(".")[1]) + result["missing_heads_model"] = list(missing_heads_model) + return result + + +def create_taskmodel( + task, model_arch, encoder, taskmodel_kwargs: Optional[Dict] = None +) -> taskmodels.Taskmodel: + """Creates, initializes and returns the task model for a given task type and encoder. + + Args: + task (Task): Task object associated with the taskmodel being created. + model_arch (ModelArchitectures.Any): Model architecture (e.g., ModelArchitectures.BERT). + encoder (PreTrainedModel): Transformer w/o heads (embedding layer + self-attention layer). + taskmodel_kwargs (Optional[Dict]): map containing any kwargs needed for taskmodel setup. + + Raises: + KeyError if task does not have valid TASK_TYPE. + + Returns: + Taskmodel (e.g., ClassificationModel) appropriate for the task type and encoder. + + """ + if model_arch in [ + ModelArchitectures.BERT, + ModelArchitectures.ROBERTA, + ModelArchitectures.ALBERT, + ModelArchitectures.XLM_ROBERTA, + ModelArchitectures.ELECTRA, + ]: + hidden_size = encoder.config.hidden_size + hidden_dropout_prob = encoder.config.hidden_dropout_prob + elif model_arch in [ + ModelArchitectures.BART, + ModelArchitectures.MBART, + ]: + hidden_size = encoder.config.d_model + hidden_dropout_prob = encoder.config.dropout + else: + raise KeyError() + + if task.TASK_TYPE == TaskTypes.CLASSIFICATION: + assert taskmodel_kwargs is None + classification_head = heads.ClassificationHead( + hidden_size=hidden_size, + hidden_dropout_prob=hidden_dropout_prob, + num_labels=len(task.LABELS), + ) + taskmodel = taskmodels.ClassificationModel( + encoder=encoder, classification_head=classification_head, + ) + elif task.TASK_TYPE == TaskTypes.REGRESSION: + assert taskmodel_kwargs is None + regression_head = heads.RegressionHead( + hidden_size=hidden_size, hidden_dropout_prob=hidden_dropout_prob, + ) + taskmodel = taskmodels.RegressionModel(encoder=encoder, regression_head=regression_head) + elif task.TASK_TYPE == TaskTypes.MULTIPLE_CHOICE: + assert taskmodel_kwargs is None + choice_scoring_head = heads.RegressionHead( + hidden_size=hidden_size, hidden_dropout_prob=hidden_dropout_prob, + ) + taskmodel = taskmodels.MultipleChoiceModel( + encoder=encoder, num_choices=task.NUM_CHOICES, choice_scoring_head=choice_scoring_head, + ) + elif task.TASK_TYPE == TaskTypes.SPAN_PREDICTION: + assert taskmodel_kwargs is None + span_prediction_head = heads.TokenClassificationHead( + hidden_size=encoder.config.hidden_size, + hidden_dropout_prob=encoder.config.hidden_dropout_prob, + num_labels=2, + ) + taskmodel = taskmodels.SpanPredictionModel( + encoder=encoder, span_prediction_head=span_prediction_head, + ) + elif task.TASK_TYPE == TaskTypes.SPAN_COMPARISON_CLASSIFICATION: + assert taskmodel_kwargs is None + span_comparison_head = heads.SpanComparisonHead( + hidden_size=hidden_size, + hidden_dropout_prob=hidden_dropout_prob, + num_spans=task.num_spans, + num_labels=len(task.LABELS), + ) + taskmodel = taskmodels.SpanComparisonModel( + encoder=encoder, span_comparison_head=span_comparison_head, + ) + elif task.TASK_TYPE == TaskTypes.MULTI_LABEL_SPAN_CLASSIFICATION: + assert taskmodel_kwargs is None + span_comparison_head = heads.SpanComparisonHead( + hidden_size=hidden_size, + hidden_dropout_prob=hidden_dropout_prob, + num_spans=task.num_spans, + num_labels=len(task.LABELS), + ) + taskmodel = taskmodels.MultiLabelSpanComparisonModel( + encoder=encoder, span_comparison_head=span_comparison_head, + ) + elif task.TASK_TYPE == TaskTypes.TAGGING: + assert taskmodel_kwargs is None + token_classification_head = heads.TokenClassificationHead( + hidden_size=hidden_size, + hidden_dropout_prob=hidden_dropout_prob, + num_labels=len(task.LABELS), + ) + taskmodel = taskmodels.TokenClassificationModel( + encoder=encoder, token_classification_head=token_classification_head, + ) + elif task.TASK_TYPE == TaskTypes.SQUAD_STYLE_QA: + assert taskmodel_kwargs is None + qa_head = heads.QAHead(hidden_size=encoder.config.hidden_size) + taskmodel = taskmodels.QAModel(encoder=encoder, qa_head=qa_head) + elif task.TASK_TYPE == TaskTypes.MASKED_LANGUAGE_MODELING: + assert taskmodel_kwargs is None + if model_arch == ModelArchitectures.BERT: + mlm_head = heads.BertMLMHead( + hidden_size=encoder.config.hidden_size, + vocab_size=encoder.config.vocab_size, + layer_norm_eps=encoder.config.layer_norm_eps, + hidden_act=encoder.config.hidden_act, + ) + elif model_arch == ModelArchitectures.ROBERTA: + mlm_head = heads.RobertaMLMHead( + hidden_size=encoder.config.hidden_size, + vocab_size=encoder.config.vocab_size, + layer_norm_eps=encoder.config.layer_norm_eps, + ) + elif model_arch == ModelArchitectures.ALBERT: + mlm_head = heads.AlbertMLMHead( + hidden_size=encoder.config.hidden_size, + embedding_size=encoder.config.embedding_size, + vocab_size=encoder.config.vocab_size, + hidden_act=encoder.config.hidden_act, + ) + elif model_arch == ModelArchitectures.XLM_ROBERTA: + mlm_head = heads.RobertaMLMHead( + hidden_size=encoder.config.hidden_size, + vocab_size=encoder.config.vocab_size, + layer_norm_eps=encoder.config.layer_norm_eps, + ) + elif model_arch in ( + ModelArchitectures.BART, + ModelArchitectures.MBART, + ModelArchitectures.ELECTRA, + ): + raise NotImplementedError() + else: + raise KeyError(model_arch) + taskmodel = taskmodels.MLMModel(encoder=encoder, mlm_head=mlm_head) + elif task.TASK_TYPE == TaskTypes.EMBEDDING: + if taskmodel_kwargs["pooler_type"] == "mean": + pooler_head = heads.MeanPoolerHead() + elif taskmodel_kwargs["pooler_type"] == "first": + pooler_head = heads.FirstPoolerHead() + else: + raise KeyError(taskmodel_kwargs["pooler_type"]) + taskmodel = taskmodels.EmbeddingModel( + encoder=encoder, pooler_head=pooler_head, layer=taskmodel_kwargs["layer"], + ) + else: + raise KeyError(task.TASK_TYPE) + return taskmodel + + +def get_encoder(model_arch, ancestor_model): + """From model architecture, get the encoder (encoder = embedding layer + self-attention layer). + + This function will return the "The bare Bert Model transformer outputting raw hidden-states + without any specific head on top", when provided with ModelArchitectures and BertForPreTraining + model. See Hugging Face's BertForPreTraining and BertModel documentation for more info. + + Args: + model_arch: Model architecture. + ancestor_model: Model with pretraining heads attached. + + Raises: + KeyError if ModelArchitectures + + Returns: + Bare pretrained model outputting raw hidden-states without a specific head on top. + + """ + if model_arch == ModelArchitectures.BERT: + return ancestor_model.bert + elif model_arch == ModelArchitectures.ROBERTA: + return ancestor_model.roberta + elif model_arch == ModelArchitectures.ALBERT: + return ancestor_model.albert + elif model_arch == ModelArchitectures.XLM_ROBERTA: + return ancestor_model.roberta + elif model_arch in (ModelArchitectures.BART, ModelArchitectures.MBART): + return ancestor_model.model + elif model_arch == ModelArchitectures.ELECTRA: + return ancestor_model.electra + else: + raise KeyError(model_arch) + + +@dataclass +class TransformersClassSpec: + config_class: Any + tokenizer_class: Any + model_class: Any + + +TRANSFORMERS_CLASS_SPEC_DICT = { + ModelArchitectures.BERT: TransformersClassSpec( + config_class=transformers.BertConfig, + tokenizer_class=transformers.BertTokenizer, + model_class=transformers.BertForPreTraining, + ), + ModelArchitectures.ROBERTA: TransformersClassSpec( + config_class=transformers.RobertaConfig, + tokenizer_class=transformers.RobertaTokenizer, + model_class=transformers.RobertaForMaskedLM, + ), + ModelArchitectures.ALBERT: TransformersClassSpec( + config_class=transformers.AlbertConfig, + tokenizer_class=transformers.AlbertTokenizer, + model_class=transformers.AlbertForMaskedLM, + ), + ModelArchitectures.XLM_ROBERTA: TransformersClassSpec( + config_class=transformers.XLMRobertaConfig, + tokenizer_class=transformers.XLMRobertaTokenizer, + model_class=transformers.XLMRobertaForMaskedLM, + ), + ModelArchitectures.BART: TransformersClassSpec( + config_class=transformers.BartConfig, + tokenizer_class=transformers.BartTokenizer, + model_class=transformers.BartForConditionalGeneration, + ), + ModelArchitectures.MBART: TransformersClassSpec( + config_class=transformers.BartConfig, + tokenizer_class=transformers.MBartTokenizer, + model_class=transformers.BartForConditionalGeneration, + ), + ModelArchitectures.ELECTRA: TransformersClassSpec( + config_class=transformers.ElectraConfig, + tokenizer_class=transformers.ElectraTokenizer, + model_class=transformers.ElectraForPreTraining, + ), +} + + +def get_taskmodel_and_task_names(task_to_taskmodel_map: Dict[str, str]) -> Dict[str, List[str]]: + """Get mapping from task model name to the list of task names associated with that task model. + + Args: + task_to_taskmodel_map (Dict[str, str]): map from task name to task model name. + + Returns: + Dict[str, List[str]] map of task model names to lists of task names using that task model. + + """ + taskmodel_and_task_names = {} + for task_name, taskmodel_name in task_to_taskmodel_map.items(): + if taskmodel_name not in taskmodel_and_task_names: + taskmodel_and_task_names[taskmodel_name] = [] + taskmodel_and_task_names[taskmodel_name].append(task_name) + return taskmodel_and_task_names + + +def get_model_arch_from_jiant_model(jiant_model: nn.Module) -> ModelArchitectures: + return ModelArchitectures.from_encoder(encoder=jiant_model.encoder) + + +MODEL_PREFIX = { + ModelArchitectures.BERT: "bert", + ModelArchitectures.ROBERTA: "roberta", + ModelArchitectures.ALBERT: "albert", + ModelArchitectures.XLM_ROBERTA: "xlm-roberta", + ModelArchitectures.BART: "model", + ModelArchitectures.MBART: "model", + ModelArchitectures.ELECTRA: "electra", +} + + +def get_ancestor_model(transformers_class_spec, model_config_path): + """Load the model config from a file, configure the model, and return the model. + + This function returns the model class with all the pretrained weights. E.g., for BERT this is + BertForPreTraining which includes masked language modeling and next sentence prediction heads. + + Args: + transformers_class_spec (TransformersClassSpec): has refs to model, tokenizer, and config. + model_config_path (str): Path to the JSON file containing the configuration parameters. + + Returns: + Configured model. + + """ + config = transformers_class_spec.config_class.from_json_file(model_config_path) + model = transformers_class_spec.model_class(config) + return model diff --git a/jiant/proj/main/modeling/primary.py b/jiant/proj/main/modeling/primary.py new file mode 100644 index 000000000..a87cf7e8e --- /dev/null +++ b/jiant/proj/main/modeling/primary.py @@ -0,0 +1,87 @@ +from typing import Dict, Union + +import torch.nn as nn + +import jiant.proj.main.modeling.taskmodels as taskmodels +import jiant.tasks as tasks +from jiant.proj.main.components.outputs import construct_output_from_dict + + +class JiantModel(nn.Module): + def __init__( + self, + task_dict: Dict[str, tasks.Task], + encoder: nn.Module, + taskmodels_dict: Dict[str, taskmodels.Taskmodel], + task_to_taskmodel_map: Dict[str, str], + tokenizer, + ): + super().__init__() + self.task_dict = task_dict + self.encoder = encoder + self.taskmodels_dict = nn.ModuleDict(taskmodels_dict) + self.task_to_taskmodel_map = task_to_taskmodel_map + self.tokenizer = tokenizer + + def forward(self, batch: tasks.BatchMixin, task: tasks.Task, compute_loss: bool = False): + """Calls to this forward method are delegated to the forward of the appropriate taskmodel. + + When JiantModel forward is called, the task name from the task argument is used as a key + to select the appropriate submodule/taskmodel, and that taskmodel's forward is called. + + Args: + batch (tasks.BatchMixin): model input. + task (tasks.Task): task to which to delegate the forward call. + compute_loss (bool): whether to calculate and return the loss. + + Returns: + Dict containing the model output, optionally including the loss. + + """ + if isinstance(batch, dict): + batch = task.Batch.from_dict(batch) + if isinstance(task, str): + task_name = task + task = self.task_dict[task] + else: + task_name = task.name + task = task + taskmodel_key = self.task_to_taskmodel_map[task_name] + taskmodel = self.taskmodels_dict[taskmodel_key] + return taskmodel( + batch=batch, task=task, tokenizer=self.tokenizer, compute_loss=compute_loss, + ).to_dict() + + +def wrap_jiant_forward( + jiant_model: Union[JiantModel, nn.DataParallel], + batch: tasks.BatchMixin, + task: tasks.Task, + compute_loss: bool = False, +): + """Wrapper to repackage model inputs using dictionaries for compatibility with DataParallel. + + Wrapper that converts batches (type tasks.BatchMixin) to dictionaries before delegating to + JiantModel's forward method, and then converts the resulting model output dict into the + appropriate model output dataclass. + + Args: + jiant_model (Union[JiantModel, nn.DataParallel]): + batch (tasks.BatchMixin): model input batch. + task (tasks.Task): Task object passed for access in the taskmodel. + compute_loss (bool): True if loss should be computed, False otherwise. + + Returns: + Union[LogitsOutput, LogitsAndLossOutput, EmbeddingOutput]: model output dataclass. + + """ + assert isinstance(jiant_model, (JiantModel, nn.DataParallel)) + is_multi_gpu = isinstance(jiant_model, nn.DataParallel) + model_output = construct_output_from_dict( + jiant_model( + batch=batch.to_dict() if is_multi_gpu else batch, task=task, compute_loss=compute_loss, + ) + ) + if is_multi_gpu: + model_output.loss = model_output.loss.mean() + return model_output diff --git a/jiant/proj/main/modeling/taskmodels.py b/jiant/proj/main/modeling/taskmodels.py new file mode 100644 index 000000000..9de891469 --- /dev/null +++ b/jiant/proj/main/modeling/taskmodels.py @@ -0,0 +1,396 @@ +import abc +from dataclasses import dataclass +from typing import Any + +import torch +import torch.nn as nn + +import jiant.proj.main.modeling.heads as heads +import jiant.utils.transformer_utils as transformer_utils +from jiant.proj.main.components.outputs import LogitsOutput, LogitsAndLossOutput +from jiant.utils.python.datastructures import take_one +from jiant.shared.model_setup import ModelArchitectures + + +class Taskmodel(nn.Module, metaclass=abc.ABCMeta): + def __init__(self, encoder): + super().__init__() + self.encoder = encoder + + def forward(self, batch, task, tokenizer, compute_loss: bool = False): + raise NotImplementedError + + +class ClassificationModel(Taskmodel): + def __init__(self, encoder, classification_head: heads.ClassificationHead): + super().__init__(encoder=encoder) + self.classification_head = classification_head + + def forward(self, batch, task, tokenizer, compute_loss: bool = False): + encoder_output = get_output_from_encoder_and_batch(encoder=self.encoder, batch=batch) + logits = self.classification_head(pooled=encoder_output.pooled) + if compute_loss: + loss_fct = nn.CrossEntropyLoss() + loss = loss_fct( + logits.view(-1, self.classification_head.num_labels), batch.label_id.view(-1), + ) + return LogitsAndLossOutput(logits=logits, loss=loss, other=encoder_output.other) + else: + return LogitsOutput(logits=logits, other=encoder_output.other) + + +class RegressionModel(Taskmodel): + def __init__(self, encoder, regression_head: heads.RegressionHead): + super().__init__(encoder=encoder) + self.regression_head = regression_head + + def forward(self, batch, task, tokenizer, compute_loss: bool = False): + encoder_output = get_output_from_encoder_and_batch(encoder=self.encoder, batch=batch) + # TODO: Abuse of notation - these aren't really logits (Issue #45) + logits = self.regression_head(pooled=encoder_output.pooled) + if compute_loss: + loss_fct = nn.MSELoss() + loss = loss_fct(logits.view(-1), batch.label.view(-1)) + return LogitsAndLossOutput(logits=logits, loss=loss, other=encoder_output.other) + else: + return LogitsOutput(logits=logits, other=encoder_output.other) + + +class MultipleChoiceModel(Taskmodel): + def __init__(self, encoder, num_choices: int, choice_scoring_head: heads.RegressionHead): + super().__init__(encoder=encoder) + self.num_choices = num_choices + self.choice_scoring_head = choice_scoring_head + + def forward(self, batch, task, tokenizer, compute_loss: bool = False): + input_ids = batch.input_ids + segment_ids = batch.segment_ids + input_mask = batch.input_mask + + choice_score_list = [] + encoder_output_other_ls = [] + for i in range(self.num_choices): + encoder_output = get_output_from_encoder( + encoder=self.encoder, + input_ids=input_ids[:, i], + segment_ids=segment_ids[:, i], + input_mask=input_mask[:, i], + ) + choice_score = self.choice_scoring_head(pooled=encoder_output.pooled) + choice_score_list.append(choice_score) + encoder_output_other_ls.append(encoder_output.other) + + reshaped_outputs = [] + if encoder_output_other_ls[0]: + for j in range(len(encoder_output_other_ls[0])): + reshaped_outputs.append( + [ + torch.stack([misc[j][layer_i] for misc in encoder_output_other_ls], dim=1) + for layer_i in range(len(encoder_output_other_ls[0][0])) + ] + ) + reshaped_outputs = tuple(reshaped_outputs) + + logits = torch.cat( + [choice_score.unsqueeze(1).squeeze(-1) for choice_score in choice_score_list], dim=1 + ) + + if compute_loss: + loss_fct = nn.CrossEntropyLoss() + loss = loss_fct(logits.view(-1, self.num_choices), batch.label_id.view(-1)) + return LogitsAndLossOutput(logits=logits, loss=loss, other=reshaped_outputs) + else: + return LogitsOutput(logits=logits, other=reshaped_outputs) + + +class SpanComparisonModel(Taskmodel): + def __init__(self, encoder, span_comparison_head: heads.SpanComparisonHead): + super().__init__(encoder=encoder) + self.span_comparison_head = span_comparison_head + + def forward(self, batch, task, tokenizer, compute_loss: bool = False): + encoder_output = get_output_from_encoder_and_batch(encoder=self.encoder, batch=batch) + logits = self.span_comparison_head(unpooled=encoder_output.unpooled, spans=batch.spans) + if compute_loss: + loss_fct = nn.CrossEntropyLoss() + loss = loss_fct( + logits.view(-1, self.span_comparison_head.num_labels), batch.label_id.view(-1), + ) + return LogitsAndLossOutput(logits=logits, loss=loss, other=encoder_output.other) + else: + return LogitsOutput(logits=logits, other=encoder_output.other) + + +class SpanPredictionModel(Taskmodel): + def __init__(self, encoder, span_prediction_head: heads.TokenClassificationHead): + super().__init__(encoder=encoder) + self.offset_margin = 1000 + # 1000 is a big enough number that exp(-1000) will be strict 0 in float32. + # So that if we add 1000 to the valid dimensions in the input of softmax, + # we can guarantee the output distribution will only be non-zero at those dimensions. + self.span_prediction_head = span_prediction_head + + def forward(self, batch, task, tokenizer, compute_loss: bool = False): + encoder_output = get_output_from_encoder_and_batch(encoder=self.encoder, batch=batch) + logits = self.span_prediction_head(unpooled=encoder_output.unpooled) + # Ensure logits in valid range is at least self.offset_margin higher than others + logits_offset = logits.max() - logits.min() + self.offset_margin + logits = logits + logits_offset * batch.selection_token_mask.unsqueeze(dim=2) + if compute_loss: + loss_fct = nn.CrossEntropyLoss() + loss = loss_fct( + logits.transpose(dim0=1, dim1=2).flatten(end_dim=1), batch.gt_span_idxs.flatten(), + ) + return LogitsAndLossOutput(logits=logits, loss=loss, other=encoder_output.other) + else: + return LogitsOutput(logits=logits, other=encoder_output.other) + + +class MultiLabelSpanComparisonModel(Taskmodel): + def __init__(self, encoder, span_comparison_head: heads.SpanComparisonHead): + super().__init__(encoder=encoder) + self.span_comparison_head = span_comparison_head + + def forward(self, batch, task, tokenizer, compute_loss: bool = False): + encoder_output = get_output_from_encoder_and_batch(encoder=self.encoder, batch=batch) + logits = self.span_comparison_head(unpooled=encoder_output.unpooled, spans=batch.spans) + if compute_loss: + loss_fct = nn.BCEWithLogitsLoss() + loss = loss_fct( + logits.view(-1, self.span_comparison_head.num_labels), batch.label_ids.float(), + ) + return LogitsAndLossOutput(logits=logits, loss=loss, other=encoder_output.other) + else: + return LogitsOutput(logits=logits, other=encoder_output.other) + + +class TokenClassificationModel(Taskmodel): + """From RobertaForTokenClassification""" + + def __init__(self, encoder, token_classification_head: heads.TokenClassificationHead): + super().__init__(encoder=encoder) + self.token_classification_head = token_classification_head + + def forward(self, batch, task, tokenizer, compute_loss: bool = False): + encoder_output = get_output_from_encoder_and_batch(encoder=self.encoder, batch=batch) + logits = self.token_classification_head(unpooled=encoder_output.unpooled) + if compute_loss: + loss_fct = nn.CrossEntropyLoss() + active_loss = batch.label_mask.view(-1) == 1 + active_logits = logits.view(-1, self.token_classification_head.num_labels)[active_loss] + active_labels = batch.label_ids.view(-1)[active_loss] + loss = loss_fct(active_logits, active_labels) + return LogitsAndLossOutput(logits=logits, loss=loss, other=encoder_output.other) + else: + return LogitsOutput(logits=logits, other=encoder_output.other) + + +class QAModel(Taskmodel): + def __init__(self, encoder, qa_head: heads.QAHead): + super().__init__(encoder=encoder) + self.qa_head = qa_head + + def forward(self, batch, task, tokenizer, compute_loss: bool = False): + encoder_output = get_output_from_encoder_and_batch(encoder=self.encoder, batch=batch) + logits = self.qa_head(unpooled=encoder_output.unpooled) + if compute_loss: + loss = compute_qa_loss( + logits=logits, + start_positions=batch.start_position, + end_positions=batch.end_position, + ) + return LogitsAndLossOutput(logits=logits, loss=loss, other=encoder_output.other) + else: + return LogitsOutput(logits=logits, other=encoder_output.other) + + +class MLMModel(Taskmodel): + def __init__(self, encoder, mlm_head: heads.BaseMLMHead): + super().__init__(encoder=encoder) + self.mlm_head = mlm_head + + def forward(self, batch, task, tokenizer, compute_loss: bool = False): + masked_batch = batch.get_masked( + mlm_probability=task.mlm_probability, tokenizer=tokenizer, do_mask=task.do_mask, + ) + encoder_output = get_output_from_encoder( + encoder=self.encoder, + input_ids=masked_batch.masked_input_ids, + segment_ids=masked_batch.segment_ids, + input_mask=masked_batch.input_mask, + ) + logits = self.mlm_head(unpooled=encoder_output.unpooled) + if compute_loss: + loss = compute_mlm_loss(logits=logits, masked_lm_labels=masked_batch.masked_lm_labels) + return LogitsAndLossOutput(logits=logits, loss=loss, other=encoder_output.other) + else: + return LogitsOutput(logits=logits, other=encoder_output.other) + + +class EmbeddingModel(Taskmodel): + def __init__(self, encoder, pooler_head: heads.AbstractPoolerHead, layer): + super().__init__(encoder=encoder) + self.pooler_head = pooler_head + self.layer = layer + + def forward(self, batch, task, tokenizer, compute_loss: bool = False): + with transformer_utils.output_hidden_states_context(self.encoder): + encoder_output = get_output_from_encoder_and_batch(encoder=self.encoder, batch=batch) + # A tuple of layers of hidden states + hidden_states = take_one(encoder_output.other) + layer_hidden_states = hidden_states[self.layer] + + if isinstance(self.pooler_head, heads.MeanPoolerHead): + logits = self.pooler_head(unpooled=layer_hidden_states, input_mask=batch.input_mask) + elif isinstance(self.pooler_head, heads.FirstPoolerHead): + logits = self.pooler_head(layer_hidden_states) + else: + raise TypeError(type(self.pooler_head)) + + # TODO: Abuse of notation - these aren't really logits (Issue #45) + if compute_loss: + # TODO: make this optional? (Issue #45) + return LogitsAndLossOutput( + logits=logits, + loss=torch.tensor([0.0]), # This is a horrible hack + other=encoder_output.other, + ) + else: + return LogitsOutput(logits=logits, other=encoder_output.other) + + +@dataclass +class EncoderOutput: + pooled: torch.Tensor + unpooled: torch.Tensor + other: Any = None + # Extend later with attention, hidden_acts, etc + + +def get_output_from_encoder_and_batch(encoder, batch) -> EncoderOutput: + """Pass batch to encoder, return encoder model output. + + Args: + encoder: bare model outputting raw hidden-states without any specific head. + batch: Batch object (containing token indices, token type ids, and attention mask). + + Returns: + EncoderOutput containing pooled and unpooled model outputs as well as any other outputs. + + """ + return get_output_from_encoder( + encoder=encoder, + input_ids=batch.input_ids, + segment_ids=batch.segment_ids, + input_mask=batch.input_mask, + ) + + +def get_output_from_encoder(encoder, input_ids, segment_ids, input_mask) -> EncoderOutput: + """Pass inputs to encoder, return encoder output. + + Args: + encoder: bare model outputting raw hidden-states without any specific head. + input_ids: token indices (see huggingface.co/transformers/glossary.html#input-ids). + segment_ids: token type ids (see huggingface.co/transformers/glossary.html#token-type-ids). + input_mask: attention mask (see huggingface.co/transformers/glossary.html#attention-mask). + + Raises: + RuntimeError if encoder output contains less than 2 elements. + + Returns: + EncoderOutput containing pooled and unpooled model outputs as well as any other outputs. + + """ + model_arch = ModelArchitectures.from_encoder(encoder) + if model_arch in [ + ModelArchitectures.BERT, + ModelArchitectures.ROBERTA, + ModelArchitectures.ALBERT, + ModelArchitectures.XLM_ROBERTA, + ]: + pooled, unpooled, other = get_output_from_standard_transformer_models( + encoder=encoder, input_ids=input_ids, segment_ids=segment_ids, input_mask=input_mask, + ) + elif model_arch == ModelArchitectures.ELECTRA: + pooled, unpooled, other = get_output_from_electra( + encoder=encoder, input_ids=input_ids, segment_ids=segment_ids, input_mask=input_mask, + ) + elif model_arch in [ + ModelArchitectures.BART, + ModelArchitectures.MBART, + ]: + pooled, unpooled, other = get_output_from_bart_models( + encoder=encoder, input_ids=input_ids, input_mask=input_mask, + ) + else: + raise KeyError(model_arch) + + # Extend later with attention, hidden_acts, etc + if other: + return EncoderOutput(pooled=pooled, unpooled=unpooled, other=other) + else: + return EncoderOutput(pooled=pooled, unpooled=unpooled) + + +def get_output_from_standard_transformer_models(encoder, input_ids, segment_ids, input_mask): + output = encoder(input_ids=input_ids, token_type_ids=segment_ids, attention_mask=input_mask) + pooled, unpooled, other = output[1], output[0], output[2:] + return pooled, unpooled, other + + +def get_output_from_bart_models(encoder, input_ids, input_mask): + # BART and mBART and encoder-decoder architectures. + # As described in the BART paper and implemented in Transformers, + # for single input tasks, the encoder input is the sequence, + # the decode input is 1-shifted sequence, and the resulting + # sentence representation is the final decoder state. + # That's what we use for `unpooled` here. + dec_last, dec_all, enc_last, enc_all = encoder( + input_ids=input_ids, attention_mask=input_mask, output_hidden_states=True, + ) + unpooled = dec_last + + other = (enc_all + dec_all,) + + bsize, slen = input_ids.shape + batch_idx = torch.arange(bsize).to(input_ids.device) + # Get last non-pad index + pooled = unpooled[batch_idx, slen - input_ids.eq(encoder.config.pad_token_id).sum(1) - 1] + return pooled, unpooled, other + + +def get_output_from_electra(encoder, input_ids, segment_ids, input_mask): + output = encoder(input_ids=input_ids, token_type_ids=segment_ids, attention_mask=input_mask) + unpooled = output[0] + pooled = unpooled[:, 0, :] + return pooled, unpooled, output + + +def compute_mlm_loss(logits, masked_lm_labels): + vocab_size = logits.shape[-1] + loss_fct = nn.CrossEntropyLoss() + return loss_fct(logits.view(-1, vocab_size), masked_lm_labels.view(-1)) + + +def compute_qa_loss(logits, start_positions, end_positions): + # Do we want to keep them as 1 tensor, or multiple? + # bs x 2 x seq_len x 1 + + start_logits, end_logits = logits[:, 0], logits[:, 1] + # Taken from: RobertaForQuestionAnswering + # If we are on multi-GPU, split add a dimension + if len(start_positions.size()) > 1: + start_positions = start_positions.squeeze(-1) + if len(end_positions.size()) > 1: + end_positions = end_positions.squeeze(-1) + # sometimes the start/end positions are outside our model inputs, we ignore these terms + ignored_index = start_logits.size(1) + start_positions.clamp_(0, ignored_index) + end_positions.clamp_(0, ignored_index) + + loss_fct = nn.CrossEntropyLoss(ignore_index=ignored_index) + start_loss = loss_fct(start_logits, start_positions) + end_loss = loss_fct(end_logits, end_positions) + total_loss = (start_loss + end_loss) / 2 + return total_loss diff --git a/jiant/proj/main/preprocessing.py b/jiant/proj/main/preprocessing.py new file mode 100644 index 000000000..31c738389 --- /dev/null +++ b/jiant/proj/main/preprocessing.py @@ -0,0 +1,216 @@ +import numpy as np +import torch + +import jiant.shared.caching as shared_caching +import jiant.utils.torch_utils as torch_utils +from jiant.tasks.core import FeaturizationSpec, TaskTypes +from jiant.utils.display import maybe_tqdm, maybe_trange + + +class MaxValidLengthRecorder: + def __init__(self, max_seq_length): + self.max_valid_length = 0 + self.max_seq_length = max_seq_length + self.range_idx = np.arange(max_seq_length) + + def __call__(self, datum): + if "input_mask" not in datum["data_row"].get_fields(): + raise RuntimeError("Smart truncate not supported") + indexer = datum["data_row"].input_mask.reshape(-1, self.max_seq_length).max(-2) + valid_length = self.range_idx[indexer.astype(bool)].max() + 1 + self.max_valid_length = max(self.max_valid_length, valid_length) + + +def smart_truncate(dataset: torch_utils.ListDataset, max_seq_length: int, verbose: bool = False): + """Truncate data to the length of the longest example in the dataset. + + Args: + dataset (torch_utils.ListDataset): ListDataset to truncate if possible. + max_seq_length (int): The maximum total input sequence length. + verbose (bool): If True, display progress bar tracking truncation progress. + + Returns: + Tuple[torch_utils.ListDataset, int]: truncated dataset, and length of the longest sequence. + + """ + if "input_mask" not in dataset.data[0]["data_row"].get_fields(): + raise RuntimeError("Smart truncate not supported") + valid_length_ls = [] + range_idx = np.arange(max_seq_length) + for datum in dataset.data: + # TODO: document why reshape and max happen here (for cola this isn't necessary). + # (Issue #47) + indexer = datum["data_row"].input_mask.reshape(-1, max_seq_length).max(-2) + valid_length_ls.append(range_idx[indexer.astype(bool)].max() + 1) + max_valid_length = max(valid_length_ls) + + if max_valid_length == max_seq_length: + return dataset, max_seq_length + + new_datum_ls = [] + for datum in maybe_tqdm(dataset.data, desc="Smart truncate data", verbose=verbose): + new_datum_ls.append( + smart_truncate_datum( + datum=datum, max_seq_length=max_seq_length, max_valid_length=max_valid_length, + ) + ) + new_dataset = torch_utils.ListDataset(new_datum_ls) + return new_dataset, max_valid_length + + +def smart_truncate_cache( + cache: shared_caching.ChunkedFilesDataCache, + max_seq_length: int, + max_valid_length: int, + verbose: bool = False, +): + for chunk_i in maybe_trange(cache.num_chunks, desc="Smart truncate chunks", verbose=verbose): + chunk = torch.load(cache.get_chunk_path(chunk_i)) + new_chunk = [] + for datum in maybe_tqdm(chunk, desc="Smart truncate chunk-datum", verbose=verbose): + new_chunk.append( + smart_truncate_datum( + datum=datum, max_seq_length=max_seq_length, max_valid_length=max_valid_length, + ) + ) + torch.save(new_chunk, cache.get_chunk_path(chunk_i)) + + +def smart_truncate_datum(datum, max_seq_length, max_valid_length): + row_dict = datum["data_row"].to_dict() + new_row_dict = row_dict.copy() + for k, v in row_dict.items(): + if not isinstance(v, np.ndarray): + continue + if max_seq_length not in v.shape: + continue + if not v.shape.count(max_seq_length) == 1: + raise RuntimeError("confusing dimensions") + slice_ls = [] + for n in v.shape: + if n == max_seq_length: + slice_ls.append(slice(None, max_valid_length)) + else: + slice_ls.append(slice(None)) + new_row_dict[k] = v[tuple(slice_ls)] + return { + "data_row": datum["data_row"].__class__(**new_row_dict), + "metadata": datum["metadata"], + } + + +def convert_examples_to_dataset( + task, examples: list, tokenizer, feat_spec: FeaturizationSpec, phase: str, verbose=False +): + """Create ListDataset containing DataRows and metadata. + + Args: + task (Task): Task object + examples (list[Example]): list of task Examples. + tokenizer: TODO (Issue #44) + feat_spec (FeaturizationSpec): Tokenization-related metadata. + phase (str): string identifying the data subset (e.g., train, val or test). + verbose: If True, display progress bar. + + Returns: + ListDataset containing DataRows and metadata. + + """ + data_rows = tokenize_and_featurize( + task=task, + examples=examples, + tokenizer=tokenizer, + feat_spec=feat_spec, + phase=phase, + verbose=verbose, + ) + metadata = {"example_id": list(range(len(data_rows)))} + data = [] + for i, data_row in enumerate(data_rows): + metadata_row = {k: v[i] for k, v in metadata.items()} + data.append({"data_row": data_row, "metadata": metadata_row}) + return torch_utils.ListDataset(data) + + +def iter_chunk_convert_examples_to_dataset( + task, examples: list, tokenizer, feat_spec: FeaturizationSpec, phase: str, verbose=False +): + for i, data_row in enumerate( + iter_chunk_tokenize_and_featurize( + task=task, + examples=examples, + tokenizer=tokenizer, + feat_spec=feat_spec, + phase=phase, + verbose=verbose, + ) + ): + metadata = {"example_id": i} + yield {"data_row": data_row, "metadata": metadata} + + +def tokenize_and_featurize( + task, examples: list, tokenizer, feat_spec: FeaturizationSpec, phase, verbose=False +): + """Create list of DataRows containing tokenized and featurized examples. + + Args: + task (Task): Task object + examples (list[Example]): list of task Examples. + tokenizer: TODO (Issue #44) + feat_spec (FeaturizationSpec): Tokenization-related metadata. + phase (str): string identifying the data subset (e.g., train, val or test). + verbose: If True, display progress bar. + + Returns: + List DataRows containing tokenized and featurized examples. + + """ + # TODO: Better solution (Issue #48) + if task.TASK_TYPE == TaskTypes.SQUAD_STYLE_QA: + data_rows = [] + for example in maybe_tqdm(examples, desc="Tokenizing", verbose=verbose): + data_rows += example.to_feature_list( + tokenizer=tokenizer, + max_seq_length=feat_spec.max_seq_length, + doc_stride=task.doc_stride, + max_query_length=task.max_query_length, + set_type=phase, + ) + else: + data_rows = [ + example.tokenize(tokenizer).featurize(tokenizer, feat_spec) + for example in maybe_tqdm(examples, desc="Tokenizing", verbose=verbose) + ] + return data_rows + + +def iter_chunk_tokenize_and_featurize( + task, examples: list, tokenizer, feat_spec: FeaturizationSpec, phase, verbose=False +): + """Generator of DataRows containing tokenized and featurized examples. + + Args: + task (Task): Task object + examples (list[Example]): list of task Examples. + tokenizer: TODO (Issue #44) + feat_spec (FeaturizationSpec): Tokenization-related metadata. + phase (str): string identifying the data subset (e.g., train, val or test). + verbose: If True, display progress bar. + + Yields: + DataRow containing tokenized and featurized examples. + + """ + for example in maybe_tqdm(examples, desc="Tokenizing", verbose=verbose): + # TODO: Better solution (Issue #48) + if task.TASK_TYPE == TaskTypes.SQUAD_STYLE_QA: + yield from example.to_feature_list( + tokenizer=tokenizer, + max_seq_length=feat_spec.max_seq_length, + doc_stride=task.doc_stride, + max_query_length=task.max_query_length, + set_type=phase, + ) + else: + yield example.tokenize(tokenizer).featurize(tokenizer, feat_spec) diff --git a/jiant/proj/main/runner.py b/jiant/proj/main/runner.py new file mode 100644 index 000000000..623a21418 --- /dev/null +++ b/jiant/proj/main/runner.py @@ -0,0 +1,351 @@ +from typing import Dict +from dataclasses import dataclass + +import torch + +import jiant.tasks.evaluate as evaluate +import jiant.utils.torch_utils as torch_utils +from jiant.proj.main.components.container_setup import JiantTaskContainer +from jiant.proj.main.modeling.primary import JiantModel, wrap_jiant_forward +from jiant.shared.constants import PHASE +from jiant.shared.runner import ( + complex_backpropagate, + get_train_dataloader_from_cache, + get_eval_dataloader_from_cache, +) +from jiant.utils.display import maybe_tqdm +from jiant.utils.python.datastructures import InfiniteYield, ExtendedDataClassMixin + + +@dataclass +class RunnerParameters(ExtendedDataClassMixin): + local_rank: int + n_gpu: int + fp16: bool + max_grad_norm: float + + +@dataclass +class TrainState(ExtendedDataClassMixin): + global_steps: int + task_steps: Dict[str, int] + + @classmethod + def from_task_name_list(cls, task_name_list): + return cls(global_steps=0, task_steps={task_name: 0 for task_name in task_name_list}) + + def step(self, task_name): + self.task_steps[task_name] += 1 + self.global_steps += 1 + + +class JiantRunner: + def __init__( + self, + jiant_task_container: JiantTaskContainer, + jiant_model: JiantModel, + optimizer_scheduler, + device, + rparams: RunnerParameters, + log_writer, + ): + self.jiant_task_container = jiant_task_container + self.jiant_model = jiant_model + self.optimizer_scheduler = optimizer_scheduler + self.device = device + self.rparams = rparams + self.log_writer = log_writer + + self.model = self.jiant_model + + def run_train(self): + for _ in self.run_train_context(): + pass + + def run_train_context(self, verbose=True): + train_dataloader_dict = self.get_train_dataloader_dict() + train_state = TrainState.from_task_name_list( + self.jiant_task_container.task_run_config.train_task_list + ) + for _ in maybe_tqdm( + range(self.jiant_task_container.global_train_config.max_steps), + desc="Training", + verbose=verbose, + ): + self.run_train_step( + train_dataloader_dict=train_dataloader_dict, train_state=train_state + ) + yield train_state + + def resume_train_context(self, train_state, verbose=True): + train_dataloader_dict = self.get_train_dataloader_dict() + start_position = train_state.global_steps + for _ in maybe_tqdm( + range(start_position, self.jiant_task_container.global_train_config.max_steps), + desc="Training", + initial=start_position, + total=self.jiant_task_container.global_train_config.max_steps, + verbose=verbose, + ): + self.run_train_step( + train_dataloader_dict=train_dataloader_dict, train_state=train_state + ) + yield train_state + + def run_train_step(self, train_dataloader_dict: dict, train_state: TrainState): + self.jiant_model.train() + task_name, task = self.jiant_task_container.task_sampler.pop() + task_specific_config = self.jiant_task_container.task_specific_configs[task_name] + + loss_val = 0 + for i in range(task_specific_config.gradient_accumulation_steps): + batch, batch_metadata = train_dataloader_dict[task_name].pop() + batch = batch.to(self.device) + model_output = wrap_jiant_forward( + jiant_model=self.jiant_model, batch=batch, task=task, compute_loss=True, + ) + loss = self.complex_backpropagate( + loss=model_output.loss, + gradient_accumulation_steps=task_specific_config.gradient_accumulation_steps, + ) + loss_val += loss.item() + + self.optimizer_scheduler.step() + self.optimizer_scheduler.optimizer.zero_grad() + + train_state.step(task_name=task_name) + self.log_writer.write_entry( + "loss_train", + { + "task": task_name, + "task_step": train_state.task_steps[task_name], + "global_step": train_state.global_steps, + "loss_val": loss_val / task_specific_config.gradient_accumulation_steps, + }, + ) + + def run_val(self, task_name_list, use_subset=None, return_preds=False, verbose=True): + evaluate_dict = {} + val_dataloader_dict = self.get_val_dataloader_dict( + task_name_list=task_name_list, use_subset=use_subset + ) + val_labels_dict = self.get_val_labels_dict( + task_name_list=task_name_list, use_subset=use_subset + ) + for task_name in task_name_list: + task = self.jiant_task_container.task_dict[task_name] + evaluate_dict[task_name] = run_val( + val_dataloader=val_dataloader_dict[task_name], + val_labels=val_labels_dict[task_name], + jiant_model=self.jiant_model, + task=task, + device=self.device, + local_rank=self.rparams.local_rank, + return_preds=return_preds, + verbose=verbose, + ) + return evaluate_dict + + def run_test(self, task_name_list, verbose=True): + evaluate_dict = {} + test_dataloader_dict = self.get_test_dataloader_dict() + for task_name in task_name_list: + task = self.jiant_task_container.task_dict[task_name] + evaluate_dict[task_name] = run_test( + test_dataloader=test_dataloader_dict[task_name], + jiant_model=self.jiant_model, + task=task, + device=self.device, + local_rank=self.rparams.local_rank, + verbose=verbose, + ) + return evaluate_dict + + def get_train_dataloader_dict(self): + # Not currently supported distributed parallel + train_dataloader_dict = {} + for task_name in self.jiant_task_container.task_run_config.train_task_list: + task = self.jiant_task_container.task_dict[task_name] + train_cache = self.jiant_task_container.task_cache_dict[task_name]["train"] + train_batch_size = self.jiant_task_container.task_specific_configs[ + task_name + ].train_batch_size + train_dataloader_dict[task_name] = InfiniteYield( + get_train_dataloader_from_cache( + train_cache=train_cache, task=task, train_batch_size=train_batch_size, + ) + ) + return train_dataloader_dict + + def _get_eval_dataloader_dict(self, phase, task_name_list, use_subset=False): + val_dataloader_dict = {} + for task_name in task_name_list: + task = self.jiant_task_container.task_dict[task_name] + eval_cache = self.jiant_task_container.task_cache_dict[task_name][phase] + task_specific_config = self.jiant_task_container.task_specific_configs[task_name] + val_dataloader_dict[task_name] = get_eval_dataloader_from_cache( + eval_cache=eval_cache, + task=task, + eval_batch_size=task_specific_config.eval_batch_size, + subset_num=task_specific_config.eval_subset_num if use_subset else None, + ) + return val_dataloader_dict + + def get_val_dataloader_dict(self, task_name_list, use_subset=False): + return self._get_eval_dataloader_dict( + phase="val", task_name_list=task_name_list, use_subset=use_subset, + ) + + def get_val_labels_dict(self, task_name_list, use_subset=False): + val_labels_dict = {} + for task_name in task_name_list: + task_specific_config = self.jiant_task_container.task_specific_configs[task_name] + val_labels_cache = self.jiant_task_container.task_cache_dict[task_name]["val_labels"] + val_labels = val_labels_cache.get_all() + if use_subset: + val_labels = val_labels[: task_specific_config.eval_subset_num] + val_labels_dict[task_name] = val_labels + return val_labels_dict + + def get_test_dataloader_dict(self): + return self._get_eval_dataloader_dict( + task_name_list=self.jiant_task_container.task_run_config.test_task_list, + phase=PHASE.TEST, + ) + + def complex_backpropagate(self, loss, gradient_accumulation_steps): + return complex_backpropagate( + loss=loss, + optimizer=self.optimizer_scheduler.optimizer, + model=self.jiant_model, + fp16=self.rparams.fp16, + n_gpu=self.rparams.n_gpu, + gradient_accumulation_steps=gradient_accumulation_steps, + max_grad_norm=self.rparams.max_grad_norm, + ) + + def get_runner_state(self): + # TODO: Add fp16 (Issue #46) + state = { + "model": torch_utils.get_model_for_saving(self.jiant_model).state_dict(), + "optimizer": self.optimizer_scheduler.optimizer.state_dict(), + } + return state + + def load_state(self, runner_state): + torch_utils.get_model_for_saving(self.jiant_model).load_state_dict(runner_state["model"]) + self.optimizer_scheduler.optimizer.load_state_dict(runner_state["optimizer"]) + + +class CheckpointSaver: + def __init__(self, metadata, save_path): + self.metadata = metadata + self.save_path = save_path + + def save(self, runner_state: dict, metarunner_state: dict): + to_save = { + "runner_state": runner_state, + "metarunner_state": metarunner_state, + "metadata": self.metadata, + } + torch_utils.safe_save(to_save, self.save_path) + + +def run_val( + val_dataloader, + val_labels, + jiant_model: JiantModel, + task, + device, + local_rank, + return_preds=False, + verbose=True, +): + # Reminder: + # val_dataloader contains mostly PyTorch-relevant info + # val_labels might contain more details information needed for full evaluation + if not local_rank == -1: + return + jiant_model.eval() + total_eval_loss = 0 + nb_eval_steps, nb_eval_examples = 0, 0 + evaluation_scheme = evaluate.get_evaluation_scheme_for_task(task=task) + eval_accumulator = evaluation_scheme.get_accumulator() + + for step, (batch, batch_metadata) in enumerate( + maybe_tqdm(val_dataloader, desc=f"Eval ({task.name}, Val)", verbose=verbose) + ): + batch = batch.to(device) + + with torch.no_grad(): + model_output = wrap_jiant_forward( + jiant_model=jiant_model, batch=batch, task=task, compute_loss=True, + ) + batch_logits = model_output.logits.detach().cpu().numpy() + batch_loss = model_output.loss.mean().item() + total_eval_loss += batch_loss + eval_accumulator.update( + batch_logits=batch_logits, + batch_loss=batch_loss, + batch=batch, + batch_metadata=batch_metadata, + ) + + nb_eval_examples += len(batch) + nb_eval_steps += 1 + eval_loss = total_eval_loss / nb_eval_steps + tokenizer = ( + jiant_model.tokenizer + if not torch_utils.is_data_parallel(jiant_model) + else jiant_model.module.tokenizer + ) + output = { + "accumulator": eval_accumulator, + "loss": eval_loss, + "metrics": evaluation_scheme.compute_metrics_from_accumulator( + task=task, accumulator=eval_accumulator, labels=val_labels, tokenizer=tokenizer, + ), + } + if return_preds: + output["preds"] = evaluation_scheme.get_preds_from_accumulator( + task=task, accumulator=eval_accumulator, + ) + return output + + +def run_test( + test_dataloader, + jiant_model: JiantModel, + task, + device, + local_rank, + verbose=True, + return_preds=True, +): + if not local_rank == -1: + return + jiant_model.eval() + evaluation_scheme = evaluate.get_evaluation_scheme_for_task(task=task) + eval_accumulator = evaluation_scheme.get_accumulator() + + for step, (batch, batch_metadata) in enumerate( + maybe_tqdm(test_dataloader, desc=f"Eval ({task.name}, Test)", verbose=verbose) + ): + batch = batch.to(device) + + with torch.no_grad(): + model_output = wrap_jiant_forward( + jiant_model=jiant_model, batch=batch, task=task, compute_loss=False, + ) + batch_logits = model_output.logits.detach().cpu().numpy() + eval_accumulator.update( + batch_logits=batch_logits, batch_loss=0, batch=batch, batch_metadata=batch_metadata, + ) + output = { + "accumulator": eval_accumulator, + } + if return_preds: + output["preds"] = evaluation_scheme.get_preds_from_accumulator( + task=task, accumulator=eval_accumulator, + ) + return output diff --git a/jiant/proj/main/runscript.py b/jiant/proj/main/runscript.py new file mode 100644 index 000000000..46963b4e8 --- /dev/null +++ b/jiant/proj/main/runscript.py @@ -0,0 +1,257 @@ +import os +import torch + + +import jiant.proj.main.modeling.model_setup as jiant_model_setup +import jiant.proj.main.runner as jiant_runner +import jiant.proj.main.components.container_setup as container_setup +import jiant.proj.main.metarunner as jiant_metarunner +import jiant.proj.main.components.evaluate as jiant_evaluate +import jiant.shared.initialization as initialization +import jiant.shared.distributed as distributed +import jiant.shared.model_setup as model_setup +import jiant.utils.torch_utils as torch_utils +import jiant.utils.python.io as py_io +import jiant.utils.zconf as zconf + + +@zconf.run_config +class RunConfiguration(zconf.RunConfig): + # === Required parameters === # + jiant_task_container_config_path = zconf.attr(type=str, required=True) + output_dir = zconf.attr(type=str, required=True) + + # === Model parameters === # + model_type = zconf.attr(type=str, required=True) + model_path = zconf.attr(type=str, required=True) + model_config_path = zconf.attr(default=None, type=str) + model_tokenizer_path = zconf.attr(default=None, type=str) + model_load_mode = zconf.attr(default="from_transformers", type=str) + + # === Running Setup === # + do_train = zconf.attr(action="store_true") + do_val = zconf.attr(action="store_true") + do_save = zconf.attr(action="store_true") + write_val_preds = zconf.attr(action="store_true") + write_test_preds = zconf.attr(action="store_true") + eval_every_steps = zconf.attr(type=int, default=0) + save_every_steps = zconf.attr(type=int, default=0) + save_checkpoint_every_steps = zconf.attr(type=int, default=0) + no_improvements_for_n_evals = zconf.attr(type=int, default=0) + delete_checkpoint_if_done = zconf.attr(action="store_true") + force_overwrite = zconf.attr(action="store_true") + seed = zconf.attr(type=int, default=-1) + + # === Training Learning Parameters === # + learning_rate = zconf.attr(default=1e-5, type=float) + adam_epsilon = zconf.attr(default=1e-8, type=float) + max_grad_norm = zconf.attr(default=1.0, type=float) + optimizer_type = zconf.attr(default="adam", type=str) + + # Specialized config + no_cuda = zconf.attr(action="store_true") + fp16 = zconf.attr(action="store_true") + fp16_opt_level = zconf.attr(default="O1", type=str) + local_rank = zconf.attr(default=-1, type=int) + server_ip = zconf.attr(default="", type=str) + server_port = zconf.attr(default="", type=str) + + +@zconf.run_config +class ResumeConfiguration(zconf.RunConfig): + checkpoint_path = zconf.attr(type=str) + + +def setup_runner( + args: RunConfiguration, + jiant_task_container: container_setup.JiantTaskContainer, + quick_init_out, + verbose: bool = True, +) -> jiant_runner.JiantRunner: + """Setup jiant model, optimizer, and runner, and return runner. + + Args: + args (RunConfiguration): configuration carrying command line args specifying run params. + jiant_task_container (container_setup.JiantTaskContainer): task and sampler configs. + quick_init_out (QuickInitContainer): device (GPU/CPU) and logging configuration. + verbose: If True, enables printing configuration info (to standard out). + + Returns: + jiant_runner.JiantRunner + + """ + # TODO document why the distributed.only_first_process() context manager is being used here. + with distributed.only_first_process(local_rank=args.local_rank): + # load the model + jiant_model = jiant_model_setup.setup_jiant_model( + model_type=args.model_type, + model_config_path=args.model_config_path, + tokenizer_path=args.model_tokenizer_path, + task_dict=jiant_task_container.task_dict, + taskmodels_config=jiant_task_container.taskmodels_config, + ) + jiant_model_setup.delegate_load_from_path( + jiant_model=jiant_model, weights_path=args.model_path, load_mode=args.model_load_mode + ) + jiant_model.to(quick_init_out.device) + + optimizer_scheduler = model_setup.create_optimizer( + model=jiant_model, + learning_rate=args.learning_rate, + t_total=jiant_task_container.global_train_config.max_steps, + warmup_steps=jiant_task_container.global_train_config.warmup_steps, + warmup_proportion=None, + optimizer_type=args.optimizer_type, + verbose=verbose, + ) + jiant_model, optimizer = model_setup.raw_special_model_setup( + model=jiant_model, + optimizer=optimizer_scheduler.optimizer, + fp16=args.fp16, + fp16_opt_level=args.fp16_opt_level, + n_gpu=quick_init_out.n_gpu, + local_rank=args.local_rank, + ) + optimizer_scheduler.optimizer = optimizer + rparams = jiant_runner.RunnerParameters( + local_rank=args.local_rank, + n_gpu=quick_init_out.n_gpu, + fp16=args.fp16, + max_grad_norm=args.max_grad_norm, + ) + runner = jiant_runner.JiantRunner( + jiant_task_container=jiant_task_container, + jiant_model=jiant_model, + optimizer_scheduler=optimizer_scheduler, + device=quick_init_out.device, + rparams=rparams, + log_writer=quick_init_out.log_writer, + ) + return runner + + +def run_loop(args: RunConfiguration, checkpoint=None): + is_resumed = checkpoint is not None + quick_init_out = initialization.quick_init(args=args, verbose=True) + print(quick_init_out.n_gpu) + with quick_init_out.log_writer.log_context(): + jiant_task_container = container_setup.create_jiant_task_container_from_json( + jiant_task_container_config_path=args.jiant_task_container_config_path, verbose=True, + ) + runner = setup_runner( + args=args, + jiant_task_container=jiant_task_container, + quick_init_out=quick_init_out, + verbose=True, + ) + if is_resumed: + runner.load_state(checkpoint["runner_state"]) + del checkpoint["runner_state"] + checkpoint_saver = jiant_runner.CheckpointSaver( + metadata={"args": args.to_dict()}, + save_path=os.path.join(args.output_dir, "checkpoint.p"), + ) + if args.do_train: + metarunner = jiant_metarunner.JiantMetarunner( + runner=runner, + save_every_steps=args.save_every_steps, + eval_every_steps=args.eval_every_steps, + save_checkpoint_every_steps=args.save_checkpoint_every_steps, + no_improvements_for_n_evals=args.no_improvements_for_n_evals, + checkpoint_saver=checkpoint_saver, + output_dir=args.output_dir, + verbose=True, + save_best_model=args.do_save, + load_best_model=True, + log_writer=quick_init_out.log_writer, + ) + if is_resumed: + metarunner.load_state(checkpoint["metarunner_state"]) + del checkpoint["metarunner_state"] + metarunner.run_train_loop() + + if args.do_save: + torch.save( + torch_utils.get_model_for_saving(runner.jiant_model).state_dict(), + os.path.join(args.output_dir, "model.p"), + ) + + if args.do_val: + val_results_dict = runner.run_val( + task_name_list=runner.jiant_task_container.task_run_config.val_task_list, + return_preds=args.write_val_preds, + ) + jiant_evaluate.write_val_results( + val_results_dict=val_results_dict, + metrics_aggregator=runner.jiant_task_container.metrics_aggregator, + output_dir=args.output_dir, + verbose=True, + ) + if args.write_val_preds: + jiant_evaluate.write_preds( + eval_results_dict=val_results_dict, + path=os.path.join(args.output_dir, "val_preds.p"), + ) + else: + assert not args.write_val_preds + + if args.write_test_preds: + test_results_dict = runner.run_test( + task_name_list=runner.jiant_task_container.task_run_config.test_task_list, + ) + jiant_evaluate.write_preds( + eval_results_dict=test_results_dict, + path=os.path.join(args.output_dir, "test_preds.p"), + ) + + if ( + args.delete_checkpoint_if_done + and args.save_checkpoint_every_steps + and os.path.exists(os.path.join(args.output_dir, "checkpoint.p")) + ): + os.remove(os.path.join(args.output_dir, "checkpoint.p")) + + py_io.write_file("DONE", os.path.join(args.output_dir, "done_file")) + + +def run_resume(args: ResumeConfiguration): + resume(checkpoint_path=args.checkpoint_path) + + +def resume(checkpoint_path): + checkpoint = torch.load(checkpoint_path) + args = RunConfiguration.from_dict(checkpoint["metadata"]["args"]) + run_loop(args=args, checkpoint=checkpoint) + + +def run_with_continue(cl_args): + run_args = RunConfiguration.default_run_cli(cl_args=cl_args) + if os.path.exists(os.path.join(run_args.output_dir, "done_file")) or os.path.exists( + os.path.join(run_args.output_dir, "val_metrics.json") + ): + print("Already Done") + return + elif run_args.save_checkpoint_every_steps and os.path.exists( + os.path.join(run_args.output_dir, "checkpoint.p") + ): + print("Resuming") + resume(os.path.join(run_args.output_dir, "checkpoint.p")) + else: + print("Running from start") + run_loop(args=run_args) + + +def main(): + mode, cl_args = zconf.get_mode_and_cl_args() + if mode == "run": + run_loop(RunConfiguration.default_run_cli(cl_args=cl_args)) + elif mode == "continue": + run_resume(ResumeConfiguration.default_run_cli(cl_args=cl_args)) + elif mode == "run_with_continue": + run_with_continue(cl_args=cl_args) + else: + raise zconf.ModeLookupError(mode) + + +if __name__ == "__main__": + main() diff --git a/tests/tasks/__init__.py b/jiant/proj/main/scripts/__init__.py similarity index 100% rename from tests/tasks/__init__.py rename to jiant/proj/main/scripts/__init__.py diff --git a/jiant/proj/main/scripts/configurator.py b/jiant/proj/main/scripts/configurator.py new file mode 100644 index 000000000..e517894ba --- /dev/null +++ b/jiant/proj/main/scripts/configurator.py @@ -0,0 +1,287 @@ +import math +import os + +import torch + +import jiant.utils.zconf as zconf +import jiant.utils.python.io as py_io +import jiant.utils.python.datastructures as py_datastructures + + +class Registry: + configurator_dict = {} + + @classmethod + def register(cls, configurator_class): + cls.configurator_dict[configurator_class.__name__] = configurator_class + return configurator_class + + @classmethod + def get_configurator(cls, configurator_name): + if configurator_name not in cls.configurator_dict: + raise KeyError( + f"Configurator {configurator_name} not found in " + f"available configurators: {list(cls.configurator_dict)}" + ) + return cls.configurator_dict[configurator_name] + + +def get_num_examples_from_cache(cache_path): + cache_metadata_path = os.path.join(cache_path, "data_args.p") + return torch.load(cache_metadata_path)["length"] + + +def cap_examples(num_examples, cap): + if cap is None: + return num_examples + else: + return min(num_examples, cap) + + +@Registry.register +@zconf.run_config +class SimpleAPIMultiTaskConfigurator(zconf.RunConfig): + """Multi-task Configurator designed for SimpleAPI + (Task config) Need one of: + task_config_base_path + task_config_path_dict + + (Eval batch size) Need one of: + eval_batch_multiplier + eval_batch_size + + (Task cache) Need one of: + task_cache_base_path + task_cache_config_dict + + (Computing max steps) Need one of: + epochs + max_steps + + (Task name list) Specify at least one of: + train_task_name_list + train_val_task_name_list + val_task_name_list + test_task_name_list + + Required: + train_batch_size + + Optional: + gradient_accumulation_steps + eval_subset_num + num_gpus + train_examples_cap + warmup_steps_proportion + """ + + task_config_base_path = zconf.attr(type=str, default=None) + task_config_path_dict = zconf.attr(type=str, default=None) + task_cache_base_path = zconf.attr(type=str, default=None) + task_cache_config_dict = zconf.attr(type=str, default=None) + train_task_name_list = zconf.attr(type=str, default=None) + train_val_task_name_list = zconf.attr(type=str, default=None) + val_task_name_list = zconf.attr(type=str, default=None) + test_task_name_list = zconf.attr(type=str, default=None) + train_batch_size = zconf.attr(type=int, required=True) + eval_batch_multiplier = zconf.attr(type=int, default=None) + eval_batch_size = zconf.attr(type=int, default=None) + gradient_accumulation_steps = zconf.attr(type=int, default=1) + eval_subset_num = zconf.attr(type=int, default=500) + epochs = zconf.attr(type=int, default=None) + max_steps = zconf.attr(type=int, default=None) + num_gpus = zconf.attr(type=int, default=None) + train_examples_cap = zconf.attr(type=int, default=None) + warmup_steps_proportion = zconf.attr(type=float, default=0.1) + + @classmethod + def parse_task_name_list(cls, task_name_list_arg): + if task_name_list_arg is None: + return [] + elif isinstance(task_name_list_arg, str): + return task_name_list_arg.split(",") + elif isinstance(task_name_list_arg, list): + return task_name_list_arg + else: + raise TypeError(type(task_name_list_arg)) + + def create_config(self): + # === Gather task names === # + # Get the full list of tasks across all phases + task_name_list_dict = { + "train": self.parse_task_name_list(self.train_task_name_list), + "val": self.parse_task_name_list(self.val_task_name_list), + "test": self.parse_task_name_list(self.test_task_name_list), + } + if self.train_val_task_name_list is None: + task_name_list_dict["train_val"] = task_name_list_dict["train"] + else: + task_name_list_dict["train_val"] = self.parse_task_name_list( + self.train_val_task_name_list + ) + full_task_name_list = py_datastructures.get_unique_list_in_order( + task_name_list_dict.values() + ) + + # === Gather task configs === # + # Build task_config_path_dict, either via + # 1. task_config_base_path: where all caches are contained within a given folder + # 2. task_config_dict: explicitly provided dictionary to cache paths, potentially in JSON + # Use dictionary directly, or load from JSON + if self.task_config_base_path is not None: + assert self.task_config_path_dict is None + task_config_path_dict = { + task_name: os.path.join(self.task_config_base_path, f"{task_name}_config.json") + for task_name in full_task_name_list + } + else: + if isinstance(self.task_config_path_dict, str): + task_config_path_dict = py_io.read_json( + os.path.expandvars(self.task_config_path_dict) + ) + else: + task_config_path_dict = self.task_config_path_dict + + # === Gather cache === # + # Build task_cache_base_path, either via + # 1. task_cache_base_path: where all caches are contained within a given folder + # 2. task_cache_config_dict: explicitly provided dictionary to cache paths, + # potentially in JSON + if self.task_cache_base_path is not None: + assert self.task_cache_config_dict is None + task_cache_config_dict = {} + for task_name in full_task_name_list: + task_cache_config_dict[task_name] = {} + if task_name in task_name_list_dict["train"]: + task_cache_config_dict[task_name]["train"] = os.path.join( + self.task_cache_base_path, task_name, "train", + ) + if ( + task_name in task_name_list_dict["train_val"] + or task_name in task_name_list_dict["val"] + ): + task_cache_config_dict[task_name]["val"] = os.path.join( + self.task_cache_base_path, task_name, "val", + ) + task_cache_config_dict[task_name]["val_labels"] = os.path.join( + self.task_cache_base_path, task_name, "val_labels", + ) + if task_name in task_name_list_dict["test"]: + task_cache_config_dict[task_name]["test"] = os.path.join( + self.task_cache_base_path, task_name, "test", + ) + elif isinstance(self.task_cache_config_dict, str): + assert self.task_cache_base_path is None + task_cache_config_dict = py_io.read_json(self.task_cache_config_dict) + elif isinstance(task_config_path_dict, dict): + task_cache_config_dict = self.task_cache_config_dict + else: + raise RuntimeError("Need 'task_cache_base_path' or 'task_cache_dict'") + + # === Compute training steps === # + # Computing the number of training steps across multiple tasks is slightly + # trickier than expected (unless max_steps is explicitly provided) + # We need to get the number of examples for each task, divide by the + # effective batch size (batch size per gpu * grad accum steps * number of gpus) + # AND consider a common use-case where we cap the number of examples from a given task + assert (self.epochs is None) != ( + self.max_steps is None + ), "Specify only 'epochs' or 'max_steps'" + num_examples_dict = {} + capped_num_examples_dict = {} + max_steps_not_given = self.max_steps is None + if max_steps_not_given: + assert isinstance(self.epochs, (int, float)) + max_steps = 0 + else: + max_steps = self.max_steps + for task_name in task_name_list_dict["train"]: + if self.num_gpus: + # We multiply by num_gpus because 1 step is done across (potentially) multiple GPUs + effective_batch_size = ( + self.train_batch_size * self.gradient_accumulation_steps * self.num_gpus + ) + else: + effective_batch_size = self.train_batch_size * self.gradient_accumulation_steps + num_examples = get_num_examples_from_cache( + cache_path=os.path.expandvars(task_cache_config_dict[task_name]["train"]), + ) + capped_num_examples = cap_examples( + num_examples=num_examples, cap=self.train_examples_cap + ) + num_examples_dict[task_name] = num_examples + capped_num_examples_dict[task_name] = capped_num_examples + if max_steps_not_given: + max_steps += self.epochs * math.ceil(capped_num_examples / effective_batch_size) + + # === Compute eval_batch_size === # + # Eval batch size is often a multiple of train batch size, + # so we provide 2 ways to specify it + assert (self.eval_batch_size is None) != ( + self.eval_batch_multiplier is None + ), "Specify only 'eval_batch_size' or 'eval_batch_multiplier'" + if self.eval_batch_multiplier is not None: + eval_batch_size = self.train_batch_size * self.eval_batch_multiplier + else: + eval_batch_size = self.eval_batch_size + + # === Configure Sampler === # + # We sample proportionally by default, unless our training examples are capped per task + if self.train_examples_cap is None: + sampler_config = { + "sampler_type": "ProportionalMultiTaskSampler", + } + else: + sampler_config = { + "sampler_type": "SpecifiedProbMultiTaskSampler", + "task_to_unweighted_probs": capped_num_examples_dict, + } + + # === Build configuration === # + # Finally, we build our big config dictionary. Congrats! + config_dict = { + "task_config_path_dict": task_config_path_dict, + "task_cache_config_dict": task_cache_config_dict, + "sampler_config": sampler_config, + "global_train_config": { + "max_steps": int(max_steps), + "warmup_steps": int(max_steps * self.warmup_steps_proportion), + }, + "task_specific_configs_dict": { + task_name: { + "train_batch_size": self.train_batch_size, + "eval_batch_size": eval_batch_size, + "gradient_accumulation_steps": self.gradient_accumulation_steps, + "eval_subset_num": self.eval_subset_num, + } + for task_name in full_task_name_list + }, + "taskmodels_config": { + "task_to_taskmodel_map": { + task_name: task_name for task_name in full_task_name_list + }, + "taskmodel_config_map": {task_name: None for task_name in full_task_name_list}, + }, + "task_run_config": { + "train_task_list": task_name_list_dict["train"], + "train_val_task_list": task_name_list_dict["train_val"], + "val_task_list": task_name_list_dict["val"], + "test_task_list": task_name_list_dict["test"], + }, + "metric_aggregator_config": {"metric_aggregator_type": "EqualMetricAggregator"}, + } + return config_dict + + +def main(): + full_cl_args = zconf.core.get_sys_args() + assert len(full_cl_args) >= 1, "Require two arguments to start: configurator and out_path" + configurator_name, config_path, *cl_args = full_cl_args + configurator = Registry.get_configurator(configurator_name=configurator_name) + config_dict = configurator.default_run_cli(cl_args=cl_args).create_config() + os.makedirs(os.path.split(config_path)[0], exist_ok=True) + py_io.write_json(config_dict, path=config_path) + + +if __name__ == "__main__": + main() diff --git a/jiant/proj/main/tokenize_and_cache.py b/jiant/proj/main/tokenize_and_cache.py new file mode 100644 index 000000000..b84b32ece --- /dev/null +++ b/jiant/proj/main/tokenize_and_cache.py @@ -0,0 +1,214 @@ +import os + +import jiant.proj.main.preprocessing as preprocessing +import jiant.shared.caching as shared_caching +import jiant.shared.model_resolution as model_resolution +import jiant.shared.model_setup as model_setup +import jiant.tasks as tasks +import jiant.tasks.evaluate as evaluate +import jiant.utils.zconf as zconf +import jiant.utils.python.io as py_io +from jiant.shared.constants import PHASE + + +@zconf.run_config +class RunConfiguration(zconf.RunConfig): + # === Required parameters === # + task_config_path = zconf.attr(type=str, required=True) + model_type = zconf.attr(type=str, required=True) + model_tokenizer_path = zconf.attr(type=str, required=True) + output_dir = zconf.attr(type=str, required=True) + + # === Optional parameters === # + phases = zconf.attr(default="train,val", type=str) + max_seq_length = zconf.attr(default=128, type=int) + chunk_size = zconf.attr(default=10000, type=int) + smart_truncate = zconf.attr(action="store_true") + do_iter = zconf.attr(action="store_true") + skip_write_output_paths = zconf.attr(action="store_true") + + +def chunk_and_save(task, phase, examples, feat_spec, tokenizer, args: RunConfiguration): + """Convert Examples to DataRows, optionally truncate sequences if possible, and save to disk. + + Note: + If args.do_iter is True, processes data without loading whole dataset into memory. + + Args: + task: Task object + phase (str): string identifying the data subset (e.g., train, val or test). + examples (list[Example]): list of task Examples. + feat_spec: (FeaturizationSpec): Tokenization-related metadata. + tokenizer: TODO (Issue #44) + args (RunConfiguration): run configuration object. + + """ + if args.do_iter: + iter_chunk_and_save( + task=task, + phase=phase, + examples=examples, + feat_spec=feat_spec, + tokenizer=tokenizer, + args=args, + ) + else: + full_chunk_and_save( + task=task, + phase=phase, + examples=examples, + feat_spec=feat_spec, + tokenizer=tokenizer, + args=args, + ) + + +def full_chunk_and_save(task, phase, examples, feat_spec, tokenizer, args: RunConfiguration): + """Convert Examples to ListDataset, optionally truncate sequences if possible, and save to disk. + + Args: + task: Task object + phase (str): string identifying the data subset (e.g., train, val or test). + examples (list[Example]): list of task Examples. + feat_spec: (FeaturizationSpec): Tokenization-related metadata. + tokenizer: TODO (Issue #44) + args (RunConfiguration): run configuration object. + + """ + dataset = preprocessing.convert_examples_to_dataset( + task=task, + examples=examples, + feat_spec=feat_spec, + tokenizer=tokenizer, + phase=phase, + verbose=True, + ) + if args.smart_truncate: + dataset, length = preprocessing.smart_truncate( + dataset=dataset, max_seq_length=args.max_seq_length, verbose=True, + ) + os.makedirs(os.path.join(args.output_dir, phase), exist_ok=True) + py_io.write_json( + data={"truncated_to": int(length)}, + path=os.path.join(args.output_dir, phase, "smart_truncate.json"), + ) + shared_caching.chunk_and_save( + data=dataset.data, + chunk_size=args.chunk_size, + data_args=args.to_dict(), + output_dir=os.path.join(args.output_dir, phase), + ) + + +def iter_chunk_and_save(task, phase, examples, feat_spec, tokenizer, args: RunConfiguration): + """Convert Examples to DataRows, optionally truncate sequences if possible, stream to disk. + + Args: + task: Task object + phase (str): string identifying the data subset (e.g., train, val or test). + examples (list[Example]): list of task Examples. + feat_spec: (FeaturizationSpec): Tokenization-related metadata. + tokenizer: TODO (Issue #44) + args (RunConfiguration): run configuration object. + + """ + dataset_generator = preprocessing.iter_chunk_convert_examples_to_dataset( + task=task, + examples=examples, + feat_spec=feat_spec, + tokenizer=tokenizer, + phase=phase, + verbose=True, + ) + max_valid_length_recorder = preprocessing.MaxValidLengthRecorder(args.max_seq_length) + shared_caching.iter_chunk_and_save( + data=dataset_generator, + chunk_size=args.chunk_size, + data_args=args.to_dict(), + output_dir=os.path.join(args.output_dir, phase), + recorder_callback=max_valid_length_recorder, + ) + if args.smart_truncate: + preprocessing.smart_truncate_cache( + cache=shared_caching.ChunkedFilesDataCache(os.path.join(args.output_dir, phase)), + max_seq_length=args.max_seq_length, + max_valid_length=max_valid_length_recorder.max_valid_length, + verbose=True, + ) + py_io.write_json( + data={"truncated_to": int(max_valid_length_recorder.max_valid_length)}, + path=os.path.join(args.output_dir, phase, "smart_truncate.json"), + ) + + +def main(args: RunConfiguration): + task = tasks.create_task_from_config_path(config_path=args.task_config_path, verbose=True) + feat_spec = model_resolution.build_featurization_spec( + model_type=args.model_type, max_seq_length=args.max_seq_length, + ) + tokenizer = model_setup.get_tokenizer( + model_type=args.model_type, tokenizer_path=args.model_tokenizer_path, + ) + if isinstance(args.phases, str): + phases = args.phases.split(",") + else: + phases = args.phases + assert set(phases) <= {PHASE.TRAIN, PHASE.VAL, PHASE.TEST} + + paths_dict = {} + os.makedirs(args.output_dir, exist_ok=True) + + if PHASE.TRAIN in phases: + chunk_and_save( + task=task, + phase=PHASE.TRAIN, + examples=task.get_train_examples(), + feat_spec=feat_spec, + tokenizer=tokenizer, + args=args, + ) + paths_dict["train"] = os.path.join(args.output_dir, PHASE.TRAIN) + + if PHASE.VAL in phases: + val_examples = task.get_val_examples() + chunk_and_save( + task=task, + phase=PHASE.VAL, + examples=val_examples, + feat_spec=feat_spec, + tokenizer=tokenizer, + args=args, + ) + evaluation_scheme = evaluate.get_evaluation_scheme_for_task(task) + shared_caching.chunk_and_save( + data=evaluation_scheme.get_labels_from_cache_and_examples( + task=task, + cache=shared_caching.ChunkedFilesDataCache( + os.path.join(args.output_dir, PHASE.VAL) + ), + examples=val_examples, + ), + chunk_size=args.chunk_size, + data_args=args.to_dict(), + output_dir=os.path.join(args.output_dir, "val_labels"), + ) + paths_dict[PHASE.VAL] = os.path.join(args.output_dir, PHASE.VAL) + paths_dict["val_labels"] = os.path.join(args.output_dir, "val_labels") + + if PHASE.TEST in phases: + chunk_and_save( + task=task, + phase=PHASE.TEST, + examples=task.get_test_examples(), + feat_spec=feat_spec, + tokenizer=tokenizer, + args=args, + ) + paths_dict[PHASE.TEST] = os.path.join(args.output_dir, PHASE.TEST) + + if not args.skip_write_output_paths: + py_io.write_json(data=paths_dict, path=os.path.join(args.output_dir, "paths.json")) + + +if __name__ == "__main__": + main(args=RunConfiguration.run_cli_json_prepend()) diff --git a/jiant/proj/main/write_task_configs.py b/jiant/proj/main/write_task_configs.py new file mode 100644 index 000000000..908b22564 --- /dev/null +++ b/jiant/proj/main/write_task_configs.py @@ -0,0 +1,50 @@ +import os + +import jiant.utils.python.filesystem as py_filesystem +import jiant.utils.python.io as py_io +import jiant.utils.zconf as zconf + + +def get_task_config(task_config_templates, task_name, task_data_dir): + task_config = task_config_templates[task_name].copy() + task_config["paths"] = {} + for key, rel_path in task_config["rel_paths"].items(): + if isinstance(rel_path, dict): + raise RuntimeError("Nested path dicts not currently supported") + task_config["paths"][key] = os.path.join(task_data_dir, rel_path) + assert os.path.exists(task_config["paths"][key]) + del task_config["rel_paths"] + return task_config + + +def create_and_write_task_config(task_name, task_data_dir, task_config_path): + task_config_templates = py_io.read_json( + py_filesystem.get_code_asset_path("assets/simple_api/task_config_templates.json") + ) + task_config = get_task_config( + task_config_templates=task_config_templates, + task_name=task_name, + task_data_dir=task_data_dir, + ) + os.makedirs(os.path.split(task_config_path)[0], exist_ok=True) + py_io.write_json(task_config, task_config_path) + + +@zconf.run_config +class RunConfiguration(zconf.RunConfig): + # === Required parameters === # + task_name = zconf.attr(type=str, required=True) + task_data_dir = zconf.attr(type=str, required=True) + task_config_path = zconf.attr(type=str, required=True) + + +def main(args: RunConfiguration): + create_and_write_task_config( + task_name=args.task_name, + task_data_dir=args.task_data_dir, + task_config_path=args.task_config_path, + ) + + +if __name__ == "__main__": + main(RunConfiguration.default_run_cli()) diff --git a/scripts/ccg/ccg.train b/jiant/proj/simple/__init__.py similarity index 100% rename from scripts/ccg/ccg.train rename to jiant/proj/simple/__init__.py diff --git a/jiant/proj/simple/runscript.py b/jiant/proj/simple/runscript.py new file mode 100644 index 000000000..9b4a592a7 --- /dev/null +++ b/jiant/proj/simple/runscript.py @@ -0,0 +1,384 @@ +import os + +import torch + +import jiant.proj.main.write_task_configs as write_task_configs +import jiant.proj.main.export_model as export_model +import jiant.proj.main.tokenize_and_cache as tokenize_and_cache +import jiant.proj.main.scripts.configurator as configurator +import jiant.proj.main.runscript as runscript +import jiant.shared.distributed as distributed +import jiant.utils.zconf as zconf +import jiant.utils.python.io as py_io +from jiant.utils.python.logic import replace_none + + +@zconf.run_config +class RunConfiguration(zconf.RunConfig): + # === Required parameters === # + run_name = zconf.attr(type=str, required=True) + exp_dir = zconf.attr(type=str, required=True) + data_dir = zconf.attr(type=str, required=True) + + # === Model parameters === # + model_type = zconf.attr(type=str, required=True) + model_weights_path = zconf.attr(type=str, default=None) + model_cache_path = zconf.attr(type=str, default=None) + + # === Task parameters === # + tasks = zconf.attr(type=str, default=None) + train_tasks = zconf.attr(type=str, default=None) + val_tasks = zconf.attr(type=str, default=None) + test_tasks = zconf.attr(type=str, default=None) + + # === Misc parameters === # + train_batch_size = zconf.attr(type=int, default=32) + max_seq_length = zconf.attr(type=int, default=256) + num_train_epochs = zconf.attr(type=float, default=3) + train_examples_cap = zconf.attr(type=int, default=None) + dry_run = zconf.attr(action="store_true") + create_config = zconf.attr(action="store_true") + + # === Running Setup === # + do_save = zconf.attr(action="store_true") + write_val_preds = zconf.attr(action="store_true") + write_test_preds = zconf.attr(action="store_true") + eval_every_steps = zconf.attr(type=int, default=0) + save_every_steps = zconf.attr(type=int, default=0) + save_checkpoint_every_steps = zconf.attr(type=int, default=0) + no_improvements_for_n_evals = zconf.attr(type=int, default=0) + delete_checkpoint_if_done = zconf.attr(action="store_true") + force_overwrite = zconf.attr(action="store_true") + seed = zconf.attr(type=int, default=-1) + + # === Training Learning Parameters === # + learning_rate = zconf.attr(default=1e-5, type=float) + adam_epsilon = zconf.attr(default=1e-8, type=float) + max_grad_norm = zconf.attr(default=1.0, type=float) + optimizer_type = zconf.attr(default="adam", type=str) + + # === Specialized config === # + no_cuda = zconf.attr(action="store_true") + fp16 = zconf.attr(action="store_true") + fp16_opt_level = zconf.attr(default="O1", type=str) + local_rank = zconf.attr(default=-1, type=int) + server_ip = zconf.attr(default="", type=str) + server_port = zconf.attr(default="", type=str) + + def _post_init(self): + assert self.tasks or ( + self.train_tasks or self.val_tasks or self.test_tasks + ), "Must include tasks or one of train_tasks, val_tasks, tests_tasks" + if self.tasks and (self.train_tasks or self.val_tasks or self.test_tasks): + assert ( + ([self.tasks] == self.train_tasks) + and ([self.tasks] == self.val_tasks) + and ([self.tasks] == self.test_tasks) + ), "Tasks must be same as train_tasks/val_tasks/test_tasks if both are present" + if self.tasks: + self.train_tasks = self.tasks + self.val_tasks = self.tasks + self.test_tasks = self.tasks + self.train_tasks = self.train_tasks.split(",") + self.val_tasks = self.val_tasks.split(",") + self.test_tasks = self.test_tasks.split(",") + + +def create_and_write_task_configs(task_name_list, data_dir, task_config_base_path): + os.makedirs(task_config_base_path, exist_ok=True) + task_config_path_dict = {} + for task_name in task_name_list: + task_config_path = os.path.join(task_config_base_path, f"{task_name}_config.json") + write_task_configs.create_and_write_task_config( + task_name=task_name, + task_data_dir=os.path.join(data_dir, task_name), + task_config_path=task_config_path, + ) + task_config_path_dict[task_name] = task_config_path + return task_config_path_dict + + +def run_simple(args: RunConfiguration): + + model_cache_path = replace_none( + args.model_cache_path, default=os.path.join(args.exp_dir, "models") + ) + + with distributed.only_first_process(local_rank=args.local_rank): + # === Step 1: Write task configs based on templates === # + full_task_name_list = sorted(list(set(args.train_tasks + args.val_tasks + args.test_tasks))) + task_config_path_dict = {} + if args.create_config: + task_config_path_dict = create_and_write_task_configs( + task_name_list=full_task_name_list, + data_dir=args.data_dir, + task_config_base_path=os.path.join(args.data_dir, "configs"), + ) + else: + for task_name in full_task_name_list: + task_config_path_dict[task_name] = os.path.join( + args.data_dir, "configs", f"{task_name}_config.json" + ) + + # === Step 2: Download models === # + if not os.path.exists(os.path.join(model_cache_path, args.model_type)): + print("Downloading model") + export_model.lookup_and_export_model( + model_type=args.model_type, + output_base_path=os.path.join(model_cache_path, args.model_type), + ) + + # === Step 3: Tokenize and cache === # + phase_task_dict = { + "train": args.train_tasks, + "val": args.val_tasks, + "test": args.test_tasks, + } + for task_name in full_task_name_list: + phases_to_do = [] + for phase, phase_task_list in phase_task_dict.items(): + if task_name in phase_task_list and not os.path.exists( + os.path.join(args.exp_dir, "cache", task_name, phase) + ): + phases_to_do.append(phase) + if not phases_to_do: + continue + print(f"Tokenizing Task '{task_name}' for phases '{','.join(phases_to_do)}'") + tokenize_and_cache.main( + tokenize_and_cache.RunConfiguration( + task_config_path=task_config_path_dict[task_name], + model_type=args.model_type, + model_tokenizer_path=os.path.join( + model_cache_path, args.model_type, "tokenizer" + ), + output_dir=os.path.join(args.exp_dir, "cache", task_name), + phases=phases_to_do, + # TODO: Need a strategy for task-specific max_seq_length issues (Issue #66) + max_seq_length=args.max_seq_length, + smart_truncate=True, + do_iter=True, + ) + ) + + # === Step 4: Generate jiant_task_container_config === # + # We'll do this with a configurator. Creating a jiant_task_config has a surprising + # number of moving parts. + jiant_task_container_config = configurator.SimpleAPIMultiTaskConfigurator( + task_config_base_path=os.path.join(args.data_dir, "configs"), + task_cache_base_path=os.path.join(args.exp_dir, "cache"), + train_task_name_list=args.train_tasks, + val_task_name_list=args.val_tasks, + test_task_name_list=args.test_tasks, + train_batch_size=args.train_batch_size, + eval_batch_multiplier=2, + epochs=args.num_train_epochs, + num_gpus=torch.cuda.device_count(), + train_examples_cap=args.train_examples_cap, + ).create_config() + os.makedirs(os.path.join(args.exp_dir, "run_configs"), exist_ok=True) + jiant_task_container_config_path = os.path.join( + args.exp_dir, "run_configs", f"{args.run_name}_config.json" + ) + py_io.write_json(jiant_task_container_config, path=jiant_task_container_config_path) + + # === Step 5: Train/Eval! === # + if args.model_weights_path: + model_load_mode = "partial" + model_weights_path = args.model_weights_path + else: + # From Transformers + if any(task_name.startswith("mlm_") for task_name in full_task_name_list): + model_load_mode = "from_transformers_with_mlm" + else: + model_load_mode = "from_transformers" + model_weights_path = os.path.join( + model_cache_path, args.model_type, "model", f"{args.model_type}.p" + ) + run_output_dir = os.path.join(args.exp_dir, "runs", args.run_name) + runscript.run_loop( + runscript.RunConfiguration( + # === Required parameters === # + jiant_task_container_config_path=jiant_task_container_config_path, + output_dir=run_output_dir, + # === Model parameters === # + model_type=args.model_type, + model_path=model_weights_path, + model_config_path=os.path.join( + model_cache_path, args.model_type, "model", f"{args.model_type}.json" + ), + model_tokenizer_path=os.path.join(model_cache_path, args.model_type, "tokenizer"), + model_load_mode=model_load_mode, + # === Running Setup === # + do_train=bool(args.train_tasks), + do_val=bool(args.val_tasks), + do_save=args.do_save, + write_val_preds=args.write_val_preds, + write_test_preds=args.write_test_preds, + eval_every_steps=args.eval_every_steps, + save_every_steps=args.save_every_steps, + save_checkpoint_every_steps=args.save_checkpoint_every_steps, + no_improvements_for_n_evals=args.no_improvements_for_n_evals, + delete_checkpoint_if_done=args.delete_checkpoint_if_done, + force_overwrite=args.force_overwrite, + seed=args.seed, + # === Training Learning Parameters === # + learning_rate=args.learning_rate, + adam_epsilon=args.adam_epsilon, + max_grad_norm=args.max_grad_norm, + optimizer_type=args.optimizer_type, + # === Specialized config === # + no_cuda=args.no_cuda, + fp16=args.fp16, + fp16_opt_level=args.fp16_opt_level, + local_rank=args.local_rank, + server_ip=args.server_ip, + server_port=args.server_port, + ) + ) + py_io.write_file(args.to_json(), os.path.join(run_output_dir, "simple_run_config.json")) + + +def dry_run(args: RunConfiguration): + + model_cache_path = replace_none( + args.model_cache_path, default=os.path.join(args.exp_dir, "models") + ) + + print("\n# === Step 1: Write task configs based on templates === #") + full_task_name_list = sorted(list(set(args.train_tasks + args.val_tasks + args.test_tasks))) + for task_name in full_task_name_list: + print( + f""" +python jiant/proj/main/write_configs.py \\ + --task_name {task_name} \\ + --task_data_dir {os.path.join(args.data_dir, task_name)} \\ + --task_config_path {os.path.join(args.data_dir, "configs", f"{task_name}_config.json")} +""".strip() + ) + + print("\n# === Step 2: Download models === #") + print( + f""" +python jiant/proj/main/export_model.py \\ + --model_type {args.model_type} \\ + --output_base_path {os.path.join(model_cache_path, args.model_type)} +""".strip() + ) + + print("\n# === Step 3: Tokenize and cache === #") + phase_task_dict = { + "train": args.train_tasks, + "val": args.val_tasks, + "test": args.test_tasks, + } + for task_name in full_task_name_list: + phases_to_do = [] + for phase, phase_task_list in phase_task_dict.items(): + if task_name in phase_task_list: + phases_to_do.append(phase) + print( + f""" +python jiant/proj/main/tokenize_and_cache.py \\ + --task_config_path {os.path.join(args.data_dir, "configs", f"{task_name}_config.json")} \\ + --model_type {args.model_type} \\ + --model_tokenizer_path {os.path.join(model_cache_path, args.model_type, "tokenizer")} \\ + --output_dir {os.path.join(args.exp_dir, "cache", task_name)} \\ + --phases {",".join(phases_to_do)} \\ + --max_seq_length {args.max_seq_length} \\ + --smart_truncate \\ + --do_iter +""".strip() + ) + + print("\n# === Step 4: Generate jiant_task_container_config === #") + s = f""" +python jiant/proj/main/scripts/configurator.py \\ + SimpleAPIMultiTaskConfigurator \\ + {os.path.join(args.exp_dir, "run_configs", f"{args.run_name}_config.json")} \\ + --task_config_base_path {os.path.join(args.data_dir, "configs")} \\ + --task_cache_base_path {os.path.join(args.exp_dir, "cache")} \\ + --train_task_name_list {",".join(args.train_tasks)} \\ + --val_task_name_list {",".join(args.val_tasks)} \\ + --test_task_name_list {",".join(args.test_tasks)} \\ + --train_batch_size {args.train_batch_size} \\ + --eval_batch_multiplier 2 \\ + --epochs {args.num_train_epochs} \\ + --num_gpus {torch.cuda.device_count()} +""".strip() + if args.train_examples_cap: + s += f" \\\n --train_examples_cap {args.train_examples_cap}" + print(s.strip()) + + print("\n# === Step 5: Train/Eval! === #") + if args.model_weights_path: + model_load_mode = "partial" + model_weights_path = args.model_weights_path + else: + # From Transformers + if any(task_name.startswith("mlm_") for task_name in full_task_name_list): + model_load_mode = "from_transformers_with_mlm" + else: + model_load_mode = "from_transformers" + model_weights_path = os.path.join( + model_cache_path, args.model_type, "model", f"{args.model_type}.p" + ) + s = f""" +python jiant/proj/main/runscript.py \\ + run \\ + --jiant_task_container_config_path \ +{os.path.join(args.exp_dir, "run_configs", f"{args.run_name}_config.json")} \\ + --output_dir {os.path.join(args.exp_dir, "runs", args.run_name)} \\ + --model_type {args.model_type} \\ + --model_path {model_weights_path} \\ + --model_config_path \ + {os.path.join(model_cache_path, args.model_type, "model", f"{args.model_type}.json")} \\ + --model_tokenizer_path {os.path.join(model_cache_path, args.model_type, "tokenizer")} \\ + --model_load_mode {model_load_mode} +""".strip() + if args.train_tasks: + s += " \\\n --do_train" + if args.val_tasks: + s += " \\\n --do_val" + covered_attrs = [ + "jiant_task_container_config_path", + "output_dir", + "model_type", + "model_path", + "model_config_path", + "model_tokenizer_path", + "model_load_mode", + ] + for attr in runscript.RunConfiguration.__attrs_attrs__: + if attr.name in covered_attrs: + continue + if not hasattr(args, attr.name): + continue + args_attr = getattr(args, attr.name) + if attr.default == args_attr: + continue + if attr.default is None and args_attr is None: + continue + if ( + "argparse_kwargs" in attr.metadata + and "action" in attr.metadata["argparse_kwargs"] + and attr.metadata["argparse_kwargs"]["action"] == "store_true" + ): + s += f" \\\n --{attr.name}" + else: + s += f" \\\n --{attr.name} {args_attr}" + print(s.strip()) + + +def main(): + mode, cl_args = zconf.get_mode_and_cl_args() + args = RunConfiguration.default_run_cli(cl_args=cl_args) + if mode == "run": + run_simple(args) + elif mode == "dry_run": + dry_run(args) + else: + raise zconf.ModeLookupError(mode) + + +if __name__ == "__main__": + main() diff --git a/tests/test_mlm.py b/jiant/scripts/__init__.py similarity index 100% rename from tests/test_mlm.py rename to jiant/scripts/__init__.py diff --git a/jiant/scripts/benchmarks/__init__.py b/jiant/scripts/benchmarks/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/jiant/scripts/benchmarks/benchmark_submission_formatter.py b/jiant/scripts/benchmarks/benchmark_submission_formatter.py new file mode 100644 index 000000000..4e405250f --- /dev/null +++ b/jiant/scripts/benchmarks/benchmark_submission_formatter.py @@ -0,0 +1,48 @@ +"""Translate raw prediction files for benchmark tasks into format expected by +benchmark leaderboards. +""" +import os +import argparse + +from jiant.scripts.postproc.benchmarks import GlueBenchmark, SuperglueBenchmark + + +SUPPORTED_BENCHMARKS = {"GLUE": GlueBenchmark, "SUPERGLUE": SuperglueBenchmark} + + +def main(): + parser = argparse.ArgumentParser( + description="Generate formatted test prediction files for benchmark submission" + ) + parser.add_argument( + "--input_base_path", + required=True, + help="base input path of benchmark task predictions (contains the benchmark task folders)", + ) + parser.add_argument("--output_path", required=True, help="output path for formatted files") + parser.add_argument( + "--benchmark", required=True, choices=SUPPORTED_BENCHMARKS, help="name of benchmark" + ) + parser.add_argument( + "--tasks", required=False, nargs="+", help="subset of benchmark tasks to format" + ) + args = parser.parse_args() + + benchmark = SUPPORTED_BENCHMARKS[args.benchmark] + + if args.tasks: + assert args.tasks in benchmark.TASKS + task_names = args.tasks + else: + task_names = benchmark.TASKS + + for task_name in task_names: + input_filepath = os.path.join(args.input_base_path, task_name, "test_preds.p") + output_filepath = os.path.join( + args.output_path, benchmark.BENCHMARK_SUBMISSION_FILENAMES[task_name] + ) + benchmark.write_predictions(task_name, input_filepath, output_filepath) + + +if __name__ == "__main__": + main() diff --git a/jiant/scripts/benchmarks/benchmarks.py b/jiant/scripts/benchmarks/benchmarks.py new file mode 100644 index 000000000..090daaadf --- /dev/null +++ b/jiant/scripts/benchmarks/benchmarks.py @@ -0,0 +1,73 @@ +import os +import csv +import torch + +import jiant.utils.python.io as py_io +from jiant.tasks import retrieval +from jiant.tasks.constants import GLUE_TASKS, SUPERGLUE_TASKS + + +class Benchmark: + TASKS = NotImplemented + BENCHMARK_SUBMISSION_FILENAMES = NotImplemented + + @classmethod + def write_predictions(cls, task_name: str, input_filepath: str, output_filepath: str): + raise NotImplementedError + + +# https://gluebenchmark.com/ +class GlueBenchmark(Benchmark): + TASKS = GLUE_TASKS + BENCHMARK_SUBMISSION_FILENAMES = { + "cola": "CoLA.tsv", + "sst": "SST-2.tsv", + "mrpc": "MRPC.tsv", + "stsb": "STS-B.tsv", + "mnli": "MNLI-m.tsv", + "mnli_mismatched": "MNLI-mm.tsv", + "qnli": "QNLI.tsv", + "qqp": "QQP.tsv", + "rte": "RTE.tsv", + "wnli": "WNLI.tsv", + "glue_diagnostics": "AX.tsv", + } + + @classmethod + def write_predictions(cls, task_name: str, input_filepath: str, output_filepath: str): + task = retrieval.get_task_class(task_name) + task_preds = torch.load(input_filepath)[task_name] + indexes, predictions = task.get_glue_preds(task_preds) + with open(output_filepath, "w") as f: + writer = csv.writer(f, delimiter="\t") + writer.writerow(("index", "prediction")) + writer.writerows(zip(indexes, predictions)) + + +# https://super.gluebenchmark.com/ +class SuperglueBenchmark(Benchmark): + TASKS = SUPERGLUE_TASKS + BENCHMARK_SUBMISSION_FILENAMES = { + "boolq": "BoolQ.jsonl", + "cb": "CB.jsonl", + "copa": "COPA.jsonl", + "multirc": "MultiRC.jsonl", + "record": "ReCoRD.jsonl", + "rte": "RTE.jsonl", + "wic": "WiC.jsonl", + "wsc": "WSC.jsonl", + "superglue_axb": "AX-b.jsonl", + "superglue_axg": "AX-g.jsonl", + } + + @classmethod + def write_predictions(cls, task_name: str, input_filepath: str, output_filepath: str): + task = retrieval.get_task_class(task_name) + task_preds = torch.load(input_filepath)[task_name] + formatted_preds = task.super_glue_format_preds(task_preds) + py_io.write_jsonl( + data=formatted_preds, + path=os.path.join( + SuperglueBenchmark.BENCHMARK_SUBMISSION_FILENAMES[task_name], output_filepath + ), + ) diff --git a/jiant/scripts/benchmarks/xtreme/subscripts/a_download_model.sh b/jiant/scripts/benchmarks/xtreme/subscripts/a_download_model.sh new file mode 100644 index 000000000..2d177e6eb --- /dev/null +++ b/jiant/scripts/benchmarks/xtreme/subscripts/a_download_model.sh @@ -0,0 +1,10 @@ +# Requires variables: +# MODEL_TYPE (e.g. xlm-roberta-large) +# BASE_PATH +# +# Description: +# This downloads a model (e.g. xlm-roberta-large) + +python jiant/proj/main/export_model.py \ + --model_type ${MODEL_TYPE} \ + --output_base_path ${BASE_PATH}/models/${MODEL_TYPE} diff --git a/jiant/scripts/benchmarks/xtreme/subscripts/b_download_data.sh b/jiant/scripts/benchmarks/xtreme/subscripts/b_download_data.sh new file mode 100644 index 000000000..47ea1e71f --- /dev/null +++ b/jiant/scripts/benchmarks/xtreme/subscripts/b_download_data.sh @@ -0,0 +1,15 @@ +# Requires variables: +# MODEL_TYPE (e.g. xlm-roberta-large) +# +# Description: +# This downloads the XTREME datasets, as well as MNLI and SQuAD for training + + +python jiant/scripts/download_data/runscript.py \ + download \ + --benchmark XTREME \ + --output_path ${BASE_PATH}/tasks/ +python jiant/scripts/download_data/runscript.py \ + download \ + --tasks mnli squad_v1 \ + --output_path ${BASE_PATH}/tasks/ diff --git a/jiant/scripts/benchmarks/xtreme/subscripts/c_tokenize_and_cache.sh b/jiant/scripts/benchmarks/xtreme/subscripts/c_tokenize_and_cache.sh new file mode 100644 index 000000000..0d51a18c6 --- /dev/null +++ b/jiant/scripts/benchmarks/xtreme/subscripts/c_tokenize_and_cache.sh @@ -0,0 +1,190 @@ +# Requires variables: +# MODEL_TYPE (e.g. xlm-roberta-large) +# BASE_PATH +# +# Description: +# This tokenizes and saves caches for all tasks (XTREME, MNLI, SQuAD) + +### XNLI (uses MNLI for training) +for LG in ar bg de el en es fr hi ru sw th tr ur vi zh; do + TASK=xnli_${LG} + python jiant/proj/main/tokenize_and_cache.py \ + --task_config_path ${BASE_PATH}/tasks/configs/${TASK}_config.json \ + --model_type ${MODEL_TYPE} \ + --model_tokenizer_path ${BASE_PATH}/models/${MODEL_TYPE}/tokenizer \ + --output_dir ${BASE_PATH}/cache/${MODEL_TYPE}/${TASK} \ + --phases val,test \ + --max_seq_length 256 \ + --smart_truncate +done + +### PAWS-X +TASK=pawsx_en +python jiant/proj/main/tokenize_and_cache.py \ + --task_config_path ${BASE_PATH}/tasks/configs/${TASK}_config.json \ + --model_type ${MODEL_TYPE} \ + --model_tokenizer_path ${BASE_PATH}/models/${MODEL_TYPE}/tokenizer \ + --output_dir ${BASE_PATH}/cache/${MODEL_TYPE}/${TASK} \ + --phases train,val,test \ + --max_seq_length 256 \ + --smart_truncate +for LG in ar de es fr ja ko zh; do + TASK=pawsx_${LG} + python jiant/proj/main/tokenize_and_cache.py \ + --task_config_path ${BASE_PATH}/tasks/configs/${TASK}_config.json \ + --model_type ${MODEL_TYPE} \ + --model_tokenizer_path ${BASE_PATH}/models/${MODEL_TYPE}/tokenizer \ + --output_dir ${BASE_PATH}/cache/${MODEL_TYPE}/${TASK} \ + --phases val,test \ + --max_seq_length 256 \ + --smart_truncate +done + +### UDPos +TASK=udpos_en +python jiant/proj/main/tokenize_and_cache.py \ + --task_config_path ${BASE_PATH}/tasks/configs/${TASK}_config.json \ + --model_type ${MODEL_TYPE} \ + --model_tokenizer_path ${BASE_PATH}/models/${MODEL_TYPE}/tokenizer \ + --output_dir ${BASE_PATH}/cache/${MODEL_TYPE}/${TASK} \ + --phases train,val,test \ + --max_seq_length 256 \ + --smart_truncate +for LG in af ar bg de el es et eu fa fi fr he hi hu id it ja ko mr nl pt ru ta te tr ur vi zh; do + TASK=udpos_${LG} + python jiant/proj/main/tokenize_and_cache.py \ + --task_config_path ${BASE_PATH}/tasks/configs/${TASK}_config.json \ + --model_type ${MODEL_TYPE} \ + --model_tokenizer_path ${BASE_PATH}/models/${MODEL_TYPE}/tokenizer \ + --output_dir ${BASE_PATH}/cache/${MODEL_TYPE}/${TASK} \ + --phases val,test \ + --max_seq_length 256 \ + --smart_truncate +done +for LG in kk th tl yo; do + TASK=udpos_${LG} + python jiant/proj/main/tokenize_and_cache.py \ + --task_config_path ${BASE_PATH}/tasks/configs/${TASK}_config.json \ + --model_type ${MODEL_TYPE} \ + --model_tokenizer_path ${BASE_PATH}/models/${MODEL_TYPE}/tokenizer \ + --output_dir ${BASE_PATH}/cache/${MODEL_TYPE}/${TASK} \ + --phases test \ + --max_seq_length 256 \ + --smart_truncate +done + +### PANX +TASK=panx_en +python jiant/proj/main/tokenize_and_cache.py \ + --task_config_path ${BASE_PATH}/tasks/configs/${TASK}_config.json \ + --model_type ${MODEL_TYPE} \ + --model_tokenizer_path ${BASE_PATH}/models/${MODEL_TYPE}/tokenizer \ + --output_dir ${BASE_PATH}/cache/${MODEL_TYPE}/${TASK} \ + --phases train,val,test \ + --max_seq_length 256 \ + --smart_truncate +for LG in af ar bg bn de el es et eu fa fi fr he hi hu id it ja jv ka kk ko ml mr ms my nl pt ru sw ta te th tl tr ur vi yo zh; do + TASK=panx_${LG} + python jiant/proj/main/tokenize_and_cache.py \ + --task_config_path ${BASE_PATH}/tasks/configs/${TASK}_config.json \ + --model_type ${MODEL_TYPE} \ + --model_tokenizer_path ${BASE_PATH}/models/${MODEL_TYPE}/tokenizer \ + --output_dir ${BASE_PATH}/cache/${MODEL_TYPE}/${TASK} \ + --phases val,test \ + --max_seq_length 256 \ + --smart_truncate +done + +### XQuAD (uses SQuAD for training) +for LG in ar de el en es hi ru th tr vi zh; do + TASK=xquad_${LG} + python jiant/proj/main/tokenize_and_cache.py \ + --task_config_path ${BASE_PATH}/tasks/configs/${TASK}_config.json \ + --model_type ${MODEL_TYPE} \ + --model_tokenizer_path ${BASE_PATH}/models/${MODEL_TYPE}/tokenizer \ + --output_dir ${BASE_PATH}/cache/${MODEL_TYPE}/${TASK} \ + --phases val \ + --max_seq_length 384 \ + --smart_truncate +done + +### MLQA (uses SQuAD for training) +for LG in ar de en es hi vi zh; do + TASK=mlqa_${LG}_${LG} + python jiant/proj/main/tokenize_and_cache.py \ + --task_config_path ${BASE_PATH}/tasks/configs/${TASK}_config.json \ + --model_type ${MODEL_TYPE} \ + --model_tokenizer_path ${BASE_PATH}/models/${MODEL_TYPE}/tokenizer \ + --output_dir ${BASE_PATH}/cache/${MODEL_TYPE}/${TASK} \ + --phases val,test \ + --max_seq_length 384 \ + --smart_truncate +done + +### TyDiQA +TASK=tydiqa_en +python jiant/proj/main/tokenize_and_cache.py \ + --task_config_path ${BASE_PATH}/tasks/configs/${TASK}_config.json \ + --model_type ${MODEL_TYPE} \ + --model_tokenizer_path ${BASE_PATH}/models/${MODEL_TYPE}/tokenizer \ + --output_dir ${BASE_PATH}/cache/${MODEL_TYPE}/${TASK} \ + --phases train,val \ + --max_seq_length 384 \ + --smart_truncate +for LG in ar bn fi id ko ru sw te; do + TASK=tydiqa_${LG} + python jiant/proj/main/tokenize_and_cache.py \ + --task_config_path ${BASE_PATH}/tasks/configs/${TASK}_config.json \ + --model_type ${MODEL_TYPE} \ + --model_tokenizer_path ${BASE_PATH}/models/${MODEL_TYPE}/tokenizer \ + --output_dir ${BASE_PATH}/cache/${MODEL_TYPE}/${TASK} \ + --phases val \ + --max_seq_length 384 \ + --smart_truncate +done + +### Bucc2018 +for LG in de fr ru zh; do + TASK=bucc2018_${LG} + python jiant/proj/main/tokenize_and_cache.py \ + --task_config_path ${BASE_PATH}/tasks/configs/${TASK}_config.json \ + --model_type ${MODEL_TYPE} \ + --model_tokenizer_path ${BASE_PATH}/models/${MODEL_TYPE}/tokenizer \ + --output_dir ${BASE_PATH}/cache/${MODEL_TYPE}/${TASK} \ + --phases val,test \ + --max_seq_length 512 \ + --smart_truncate +done + +### Tatoeba +for LG in af ar bg bn de el es et eu fa fi fr he hi hu id it ja jv ka kk ko ml mr nl pt ru sw ta te th tl tr ur vi zh; do + TASK=tatoeba_${LG} + python jiant/proj/main/tokenize_and_cache.py \ + --task_config_path ${BASE_PATH}/tasks/configs/${TASK}_config.json \ + --model_type ${MODEL_TYPE} \ + --model_tokenizer_path ${BASE_PATH}/models/${MODEL_TYPE}/tokenizer \ + --output_dir ${BASE_PATH}/cache/${MODEL_TYPE}/${TASK} \ + --phases val \ + --max_seq_length 512 \ + --smart_truncate +done + +### MNLI and SQuAD +TASK=mnli +python jiant/proj/main/tokenize_and_cache.py \ + --task_config_path ${BASE_PATH}/tasks/configs/${TASK}_config.json \ + --model_type ${MODEL_TYPE} \ + --model_tokenizer_path ${BASE_PATH}/models/${MODEL_TYPE}/tokenizer \ + --output_dir ${BASE_PATH}/cache/${MODEL_TYPE}/${TASK} \ + --phases train,val \ + --max_seq_length 256 \ + --smart_truncate +TASK=squad_v1 +python jiant/proj/main/tokenize_and_cache.py \ + --task_config_path ${BASE_PATH}/tasks/configs/${TASK}_config.json \ + --model_type ${MODEL_TYPE} \ + --model_tokenizer_path ${BASE_PATH}/models/${MODEL_TYPE}/tokenizer \ + --output_dir ${BASE_PATH}/cache/${MODEL_TYPE}/${TASK} \ + --phases train,val \ + --max_seq_length 384 \ + --smart_truncate diff --git a/jiant/scripts/benchmarks/xtreme/subscripts/d_write_configs.sh b/jiant/scripts/benchmarks/xtreme/subscripts/d_write_configs.sh new file mode 100644 index 000000000..cbb8832a0 --- /dev/null +++ b/jiant/scripts/benchmarks/xtreme/subscripts/d_write_configs.sh @@ -0,0 +1,78 @@ +# Requires variables: +# MODEL_TYPE (e.g. xlm-roberta-large) +# BASE_PATH +# +# Description: +# This write run-configs for each of the XTREME tasks + +mkdir -p ${BASE_PATH}/runconfigs + +# XNLI +python jiant/scripts/postproc/xtreme/xtreme_runconfig_writer.py \ + --xtreme_task xnli \ + --task_config_base_path ${BASE_PATH}/tasks/configs \ + --task_cache_base_path ${BASE_PATH}/cache/${MODEL_TYPE} \ + --epochs 2 --train_batch_size 4 --gradient_accumulation_steps 8 \ + --output_path ${BASE_PATH}/runconfigs/xnli.json + +# PAWS-X +python jiant/scripts/postproc/xtreme/xtreme_runconfig_writer.py \ + --xtreme_task pawsx \ + --task_config_base_path ${BASE_PATH}/tasks/configs \ + --task_cache_base_path ${BASE_PATH}/cache/${MODEL_TYPE} \ + --epochs 5 --train_batch_size 4 --gradient_accumulation_steps 8 \ + --output_path ${BASE_PATH}/runconfigs/pawsx.json + +# UDPOS +python jiant/scripts/postproc/xtreme/xtreme_runconfig_writer.py \ + --xtreme_task udpos \ + --task_config_base_path ${BASE_PATH}/tasks/configs \ + --task_cache_base_path ${BASE_PATH}/cache/${MODEL_TYPE} \ + --epochs 10 --train_batch_size 4 --gradient_accumulation_steps 8 \ + --output_path ${BASE_PATH}/runconfigs/udpos.json + +# PANX +python jiant/scripts/postproc/xtreme/xtreme_runconfig_writer.py \ + --xtreme_task panx \ + --task_config_base_path ${BASE_PATH}/tasks/configs \ + --task_cache_base_path ${BASE_PATH}/cache/${MODEL_TYPE} \ + --epochs 10 --train_batch_size 4 --gradient_accumulation_steps 8 \ + --output_path ${BASE_PATH}/runconfigs/panx.json + +# XQuAD +python jiant/scripts/postproc/xtreme/xtreme_runconfig_writer.py \ + --xtreme_task xquad \ + --task_config_base_path ${BASE_PATH}/tasks/configs \ + --task_cache_base_path ${BASE_PATH}/cache/${MODEL_TYPE} \ + --epochs 2 --train_batch_size 4 --gradient_accumulation_steps 4 \ + --output_path ${BASE_PATH}/runconfigs/xquad.json + +# MLQA +python jiant/scripts/postproc/xtreme/xtreme_runconfig_writer.py \ + --xtreme_task mlqa \ + --task_config_base_path ${BASE_PATH}/tasks/configs \ + --task_cache_base_path ${BASE_PATH}/cache/${MODEL_TYPE} \ + --epochs 2 --train_batch_size 4 --gradient_accumulation_steps 4 \ + --output_path ${BASE_PATH}/runconfigs/mlqa.json + +# TyDiQA +python jiant/scripts/postproc/xtreme/xtreme_runconfig_writer.py \ + --xtreme_task tydiqa \ + --task_config_base_path ${BASE_PATH}/tasks/configs \ + --task_cache_base_path ${BASE_PATH}/cache/${MODEL_TYPE} \ + --epochs 2 --train_batch_size 4 --gradient_accumulation_steps 4 \ + --output_path ${BASE_PATH}/runconfigs/tydiqa.json + +# Bucc2018 +python jiant/scripts/postproc/xtreme/xtreme_runconfig_writer.py \ + --xtreme_task bucc2018 \ + --task_config_base_path ${BASE_PATH}/tasks/configs \ + --task_cache_base_path ${BASE_PATH}/cache/${MODEL_TYPE} \ + --output_path ${BASE_PATH}/runconfigs/bucc2018.json + +# Tatoeba +python jiant/scripts/postproc/xtreme/xtreme_runconfig_writer.py \ + --xtreme_task tatoeba \ + --task_config_base_path ${BASE_PATH}/tasks/configs \ + --task_cache_base_path ${BASE_PATH}/cache/${MODEL_TYPE} \ + --output_path ${BASE_PATH}/runconfigs/tatoeba.json \ No newline at end of file diff --git a/jiant/scripts/benchmarks/xtreme/subscripts/e_run_models.sh b/jiant/scripts/benchmarks/xtreme/subscripts/e_run_models.sh new file mode 100644 index 000000000..8054509a7 --- /dev/null +++ b/jiant/scripts/benchmarks/xtreme/subscripts/e_run_models.sh @@ -0,0 +1,33 @@ +# Requires variables: +# MODEL_TYPE (e.g. xlm-roberta-large) +# BASE_PATH +# +# Description: +# This runs models for both fine-tuned and retrieval XTREME tasks +# Ideally, this should be run in parallel on a cluster. + +for TASK in xnli pawsx udpos panx xquad mlqa tydiqa; do + python jiant/proj/main/runscript.py \ + run_with_continue \ + --ZZsrc ${BASE_PATH}/models/${MODEL_TYPE}/config.json \ + --jiant_task_container_config_path ${BASE_PATH}/runconfigs/${TASK}.json \ + --model_load_mode from_transformers \ + --learning_rate 1e-5 \ + --eval_every_steps 1000 \ + --no_improvements_for_n_evals 30 \ + --do_save \ + --force_overwrite \ + --do_train --do_val \ + --output_dir ${BASE_PATH}/runs/${TASK} +done + +for TASK in bucc2018 tatoeba; do + python jiant/proj/main/runscript.py \ + run_with_continue \ + --ZZsrc ${BASE_PATH}/models/${MODEL_TYPE}/config.json \ + --jiant_task_container_config_path ${BASE_PATH}/runconfigs/${TASK}.json \ + --model_load_mode from_transformers \ + --force_overwrite \ + --do_val \ + --output_dir ${BASE_PATH}/runs/${TASK} +done diff --git a/jiant/scripts/benchmarks/xtreme/subscripts/run_all.sh b/jiant/scripts/benchmarks/xtreme/subscripts/run_all.sh new file mode 100644 index 000000000..8c06bb0f7 --- /dev/null +++ b/jiant/scripts/benchmarks/xtreme/subscripts/run_all.sh @@ -0,0 +1,9 @@ +# Requires variables: +# MODEL_TYPE (e.g. xlm-roberta-large) +# BASE_PATH + +bash a_download_model.sh +bash b_download_data.sh +bash c_tokenize_and_cache.sh +bash d_write_configs.sh +bash e_run_models.sh diff --git a/jiant/scripts/benchmarks/xtreme/xtreme_runconfig_writer.py b/jiant/scripts/benchmarks/xtreme/xtreme_runconfig_writer.py new file mode 100644 index 000000000..ad4c8418e --- /dev/null +++ b/jiant/scripts/benchmarks/xtreme/xtreme_runconfig_writer.py @@ -0,0 +1,130 @@ +import jiant.proj.main.scripts.configurator as configurator +import jiant.utils.zconf as zconf +import jiant.utils.python.io as py_io +from jiant.utils.python.datastructures import get_unique_list_in_order + + +LANGS_DICT = { + "xnli": "ar bg de el en es fr hi ru sw th tr ur vi zh".split(), + "pawsx": "de en es fr ja ko zh".split(), + "udpos": "af ar bg de el en es et eu fa fi fr he hi hu id it ja ko mr" + " nl pt ru ta te tr ur vi zh".split(), + "panx": "af ar bg bn de el en es et eu fa fi fr he hi hu id it ja jv ka kk ko ml mr ms my" + " nl pt ru sw ta te th tl tr ur vi yo zh".split(), + "xquad": "ar de el en es hi ru th tr vi zh".split(), + "mlqa": "ar de en es hi vi zh".split(), + "tydiqa": "ar bn en fi id ko ru sw te".split(), + "bucc2018": "de fr ru zh".split(), + "tatoeba": "af ar bg bn de el es et eu fa fi fr he hi hu id it ja jv ka kk ko ml mr" + " nl pt ru sw ta te th tl tr ur vi zh".split(), +} +EXTRA_UDPOS_TEST_LANGS = "kk th tl yo".split() +TRAIN_TASK_DICT = { + "xnli": "mnli", + "pawsx": "pawsx_en", + "udpos": "udpos_en", + "panx": "panx_en", + "xquad": "squad_v1", + "mlqa": "squad_v1", + "tydiqa": "tydiqa_en", +} +TRAINED_TASKS = ["xnli", "pawsx", "udpos", "panx", "xquad", "mlqa", "tydiqa"] +UNTRAINED_TASKS = ["bucc2018", "tatoeba"] + + +@zconf.run_config +class RunConfiguration(zconf.RunConfig): + xtreme_task = zconf.attr(type=str, required=True) + task_config_base_path = zconf.attr(type=str, required=True) + task_cache_base_path = zconf.attr(type=str, required=True) + output_path = zconf.attr(type=str, required=True) + + # Optional + epochs = zconf.attr(type=int, default=3) + warmup_steps_proportion = zconf.attr(type=float, default=0.1) + train_batch_size = zconf.attr(type=int, default=4) + eval_batch_multiplier = zconf.attr(type=int, default=2) + gradient_accumulation_steps = zconf.attr(type=int, default=1) + eval_subset_num = zconf.attr(type=int, default=500) + num_gpus = zconf.attr(type=int, default=1) + early_stop_on_xtreme_tasks = zconf.attr( + action="store_true", + help="False = Do early stopping on train task," + " True = Do early stopping on XTREME tasks in all languages" + " (default: False)", + ) + retrieval_layer = zconf.attr(type=int, default=14) + suppress_print = zconf.attr(action="store_true") + + +def generate_configs(args: RunConfiguration): + xtreme_task = args.xtreme_task + if xtreme_task == "mlqa": + xtreme_task_name_list = [f"{xtreme_task}_{lang}_{lang}" for lang in LANGS_DICT[xtreme_task]] + else: + xtreme_task_name_list = [f"{xtreme_task}_{lang}" for lang in LANGS_DICT[xtreme_task]] + + if xtreme_task in TRAINED_TASKS: + train_task = TRAIN_TASK_DICT[xtreme_task] + train_task_name_list = [train_task] + val_task_name_list = get_unique_list_in_order([xtreme_task_name_list, train_task_name_list]) + if args.early_stop_on_xtreme_tasks: + train_val_task_name_list = val_task_name_list + else: + train_val_task_name_list = train_task_name_list + elif xtreme_task in UNTRAINED_TASKS: + train_task_name_list = [] + val_task_name_list = xtreme_task_name_list + train_val_task_name_list = [] + else: + raise KeyError(xtreme_task) + + if xtreme_task == "udpos": + test_task_name_list = xtreme_task_name_list + [ + f"udpos_{lang}" for lang in EXTRA_UDPOS_TEST_LANGS + ] + elif xtreme_task in ["xquad", "tydiqa", "tatoeba"]: + test_task_name_list = [] + else: + test_task_name_list = xtreme_task_name_list + + if not args.suppress_print: + print("Training on:", ", ".join(train_task_name_list)) + print("Validation on:", ", ".join(val_task_name_list)) + print("Early stopping on:", ", ".join(train_val_task_name_list)) + print("Testing on:", ",".join(test_task_name_list)) + + config = configurator.SimpleAPIMultiTaskConfigurator( + task_config_base_path=args.task_config_base_path, + task_cache_base_path=args.task_cache_base_path, + train_task_name_list=train_task_name_list, + train_val_task_name_list=train_val_task_name_list, + val_task_name_list=val_task_name_list, + test_task_name_list=test_task_name_list, + epochs=args.epochs, + train_batch_size=args.train_batch_size, + eval_batch_multiplier=args.eval_batch_multiplier, + gradient_accumulation_steps=args.gradient_accumulation_steps, + eval_subset_num=args.eval_subset_num, + num_gpus=args.num_gpus, + warmup_steps_proportion=args.warmup_steps_proportion, + ).create_config() + + # Make sure all tasks use the same task head + config["taskmodels_config"]["task_to_taskmodel_map"] = { + k: xtreme_task for k, v in config["taskmodels_config"]["task_to_taskmodel_map"].items() + } + if not args.suppress_print: + print(f"Assigning all tasks to '{xtreme_task}' head") + if xtreme_task in UNTRAINED_TASKS: + # The reference implementation from the XTREME paper uses layer 14 for the + # retrieval representation. + config["taskmodels_config"]["taskmodel_config_map"] = { + xtreme_task: {"pooler_type": "mean", "layer": args.retrieval_layer} + } + + py_io.write_json(config, args.output_path) + + +if __name__ == "__main__": + generate_configs(RunConfiguration.default_run_cli()) diff --git a/jiant/scripts/benchmarks/xtreme/xtreme_submission.py b/jiant/scripts/benchmarks/xtreme/xtreme_submission.py new file mode 100644 index 000000000..45d723b02 --- /dev/null +++ b/jiant/scripts/benchmarks/xtreme/xtreme_submission.py @@ -0,0 +1,398 @@ +import os +import numpy as np +import torch + +import zconf +import jiant.utils.python.io as py_io +from jiant.utils.display import maybe_tqdm + +import jiant.shared.initialization as initialization +import jiant.shared.model_resolution as model_resolution +import jiant.proj.main.components.container_setup as container_setup +import jiant.proj.main.runner as jiant_runner +from jiant.proj.main.runscript import setup_runner +import jiant.tasks.lib.templates.squad_style.core as squad_lib +import jiant.tasks.lib.bucc2018 as bucc2018_lib +import jiant.tasks as tasks +import jiant.proj.main.components.evaluate as jiant_evaluate +from jiant.proj.main.modeling.primary import wrap_jiant_forward + + +@zconf.run_config +class RunConfiguration(zconf.RunConfig): + # === RunConfig Parameters === # + jiant_task_container_path = zconf.attr(type=str, default=None) + + # === Required Parameters === # + supertask = zconf.attr(type=str, default=None) + output_dir = zconf.attr(type=str, required=True) + + # === Optional Parameters === # + skip_if_done = zconf.attr(action="store_true") + bucc_val_metrics_path = zconf.attr( + type=str, + default=None, + help="Path to val_metrics.json for bucc2018. Contains the optimal threshold," + " to be used for generating test predictions.", + ) + + # === Model parameters === # + model_type = zconf.attr(type=str, required=True) + model_path = zconf.attr(type=str, required=True) + model_config_path = zconf.attr(default=None, type=str) + model_tokenizer_path = zconf.attr(default=None, type=str) + model_load_mode = zconf.attr(default="from_ptt", type=str) + + # === Nuisance Parameters === # + # Required for quickly setting up runner + # Remove/refactor with config refactor (Issue #66) + learning_rate = zconf.attr(default=1e-5, type=float) + adam_epsilon = zconf.attr(default=1e-8, type=float) + max_grad_norm = zconf.attr(default=1.0, type=float) + optimizer_type = zconf.attr(default="adam", type=str) + + # Specialized config + no_cuda = zconf.attr(action="store_true") + fp16 = zconf.attr(action="store_true") + fp16_opt_level = zconf.attr(default="O1", type=str) + local_rank = zconf.attr(default=-1, type=int) + server_ip = zconf.attr(default="", type=str) + server_port = zconf.attr(default="", type=str) + force_overwrite = zconf.attr(action="store_true") + seed = zconf.attr(type=int, default=-1) + + +def run_loop(args: RunConfiguration): + quick_init_out = initialization.quick_init(args=args, verbose=True) + with quick_init_out.log_writer.log_context(): + if args.jiant_task_container_path: + jiant_task_container = container_setup.create_jiant_task_container( + **py_io.read_json(args.jiant_task_container_path) + ) + else: + raise RuntimeError("Need `jiant_task_container_path` or individual config paths") + runner = setup_runner( + args=args, + jiant_task_container=jiant_task_container, + quick_init_out=quick_init_out, + verbose=True, + ) + supertask, output_dir = args.supertask, args.output_dir + if supertask in ["xnli", "pawsx"]: + generate_and_write_preds_for_classification( + runner=runner, + supertask=supertask, + output_dir=output_dir, + skip_if_done=args.skip_if_done, + ) + elif supertask in ["udpos", "panx"]: + generate_and_write_preds_for_tagging( + runner=runner, + supertask=supertask, + output_dir=output_dir, + skip_if_done=args.skip_if_done, + ) + elif supertask in ["xquad", "mlqa"]: + generate_and_write_preds_for_qa( + runner=runner, + supertask=supertask, + output_dir=output_dir, + phase="test", + skip_if_done=args.skip_if_done, + ) + elif supertask == "tydiqa": + generate_and_write_preds_for_qa( + runner=runner, + supertask="tydiqa", + output_dir=output_dir, + phase="val", + skip_if_done=args.skip_if_done, + ) + elif supertask == "bucc2018": + generate_and_write_preds_for_bucc2018( + runner=runner, + output_dir=output_dir, + bucc_val_metrics_path=args.bucc_val_metrics_path, + skip_if_done=args.skip_if_done, + ) + elif supertask == "tatoeba": + generate_and_write_preds_for_tatoeba( + runner=runner, output_dir=output_dir, skip_if_done=args.skip_if_done, + ) + else: + raise KeyError(supertask) + + +def generate_and_write_preds_for_classification( + runner: jiant_runner.JiantRunner, supertask: str, output_dir: str, skip_if_done: bool = False +): + """Write test predictions for classification tasks in XTREME submission format""" + preds_pickle_path = os.path.join(output_dir, f"{supertask}_test_preds.p") + if skip_if_done and os.path.exists(preds_pickle_path): + print(f"Skipping cause {preds_pickle_path} exists") + return + + test_results_dict = runner.run_test( + task_name_list=runner.jiant_task_container.task_run_config.test_task_list, + ) + jiant_evaluate.write_preds( + eval_results_dict=test_results_dict, path=preds_pickle_path, + ) + preds_output_dir = os.path.join(output_dir, "preds", supertask) + os.makedirs(preds_output_dir, exist_ok=True) + for task_name, task_results in test_results_dict.items(): + task = runner.jiant_task_container.task_dict[task_name] + assert isinstance(task, (tasks.XnliTask, tasks.PawsXTask)) + lang = task.language + with open(os.path.join(preds_output_dir, f"test-{lang}.tsv"), "w") as f: + for idx in task_results["preds"]: + if supertask == "xnli": + pred_label = task.ID_TO_LABEL[idx] + elif supertask == "pawsx": + pred_label = idx + else: + raise RuntimeError() + f.write(f"{pred_label}\n") + print(f"Wrote {supertask} preds for {len(test_results_dict)} languages") + + +def generate_and_write_preds_for_tagging( + runner: jiant_runner.JiantRunner, supertask: str, output_dir: str, skip_if_done: bool = False +): + """Generate and write test predictions for tagging tasks in XTREME submission format""" + preds_pickle_path = os.path.join(output_dir, f"{supertask}_test_preds.p") + if skip_if_done and os.path.exists(preds_pickle_path): + print(f"Skipping cause {preds_pickle_path} exists") + return + + test_dataloader_dict = runner.get_test_dataloader_dict() + preds_output_dir = os.path.join(output_dir, "preds", supertask) + os.makedirs(preds_output_dir, exist_ok=True) + preds_dict = {} + for task_name in runner.jiant_task_container.task_run_config.test_task_list: + task = runner.jiant_task_container.task_dict[task_name] + assert isinstance(task, (tasks.UdposTask, tasks.PanxTask)) + preds_list = get_preds_for_single_tagging_task( + task=task, test_dataloader=test_dataloader_dict[task_name], runner=runner, + ) + preds_dict[task_name] = preds_list + lang = task.language + with open(os.path.join(preds_output_dir, f"test-{lang}.tsv"), "w") as f: + for example_preds in preds_list: + for word, label in example_preds: + f.write(f"{label}\n") + f.write("\n") + torch.save(preds_dict, preds_pickle_path) + print( + f"Wrote {supertask} preds for" + f" {len(runner.jiant_task_container.task_run_config.test_task_list)} languages" + ) + + +def get_preds_for_single_tagging_task( + task, test_dataloader, runner: jiant_runner.JiantRunner, verbose: str = True +): + """Generate predictions for a single tagging task""" + jiant_model, device = runner.model, runner.device + jiant_model.eval() + test_examples = task.get_test_examples() + preds_list = [] + example_i = 0 + for step, (batch, batch_metadata) in enumerate( + maybe_tqdm(test_dataloader, desc=f"Eval ({task.name}, Test)", verbose=verbose) + ): + batch = batch.to(device) + + with torch.no_grad(): + model_output = wrap_jiant_forward( + jiant_model=jiant_model, batch=batch, task=task, compute_loss=False, + ) + batch_logits = model_output.logits.detach().cpu().numpy() + label_mask_arr = batch.label_mask.cpu().bool().numpy() + preds_arr = np.argmax(batch_logits, axis=-1) + for i in range(len(batch)): + # noinspection PyUnresolvedReferences + labels = [task.ID_TO_LABEL[class_i] for class_i in preds_arr[i][label_mask_arr[i]]] + if len(labels) == len(test_examples[example_i].tokens): + this_preds = list(zip(test_examples[example_i].tokens, labels)) + elif len(labels) < len(test_examples[example_i].tokens): + this_preds = list(zip(test_examples[example_i].tokens, labels)) + this_preds += [ + (task.LABELS[-1], token) + for token in test_examples[example_i].tokens[len(labels) :] + ] + else: + raise RuntimeError + + preds_list.append(this_preds) + example_i += 1 + return preds_list + + +def generate_and_write_preds_for_qa( + runner, supertask: str, output_dir: str, phase: str, skip_if_done: bool = False +): + """Generate predictions (test) for QA tasks and write them in XTREME submission format""" + preds_pickle_path = os.path.join(output_dir, f"{supertask}_test_preds.p") + if skip_if_done and os.path.exists(preds_pickle_path): + print(f"Skipping cause {preds_pickle_path} exists") + return + + if phase == "val": + task_name_list = runner.jiant_task_container.task_run_config.val_task_list + elif phase == "test": + task_name_list = runner.jiant_task_container.task_run_config.test_task_list + else: + raise KeyError(phase) + task_name_list = [task_name for task_name in task_name_list if task_name.startswith(supertask)] + if phase == "val": + test_results_dict = runner.run_val(task_name_list=task_name_list) + elif phase == "test": + test_results_dict = {} + test_dataloader_dict = runner.get_test_dataloader_dict() + for task_name in task_name_list: + test_results_dict[task_name] = jiant_runner.run_test( + test_dataloader=test_dataloader_dict[task_name], + jiant_model=runner.jiant_model, + task=runner.jiant_task_container.task_dict[task_name], + device=runner.device, + local_rank=runner.rparams.local_rank, + return_preds=False, + verbose=True, + ) + else: + raise KeyError(phase) + + # Generate QA preds + tokenizer = runner.model.tokenizer + for task_name in task_name_list: + task_results = test_results_dict[task_name] + task = runner.jiant_task_container.task_dict[task_name] + logits = task_results["accumulator"].get_accumulated() + lang = get_qa_language(supertask=supertask, task=task) + if phase == "val": + cached = runner.get_val_dataloader_dict([task_name])[ + task_name + ].dataset.chunked_file_data_cache.get_all() + elif phase == "test": + cached = runner.get_test_dataloader_dict()[ + task_name + ].dataset.chunked_file_data_cache.get_all() + else: + raise KeyError(phase) + data_rows = [row["data_row"] for row in cached] + results, predictions = squad_lib.compute_predictions_logits_v3( + data_rows=data_rows, + logits=logits, + n_best_size=task.n_best_size, + max_answer_length=task.max_answer_length, + do_lower_case=model_resolution.resolve_is_lower_case(tokenizer), + version_2_with_negative=task.version_2_with_negative, + null_score_diff_threshold=task.null_score_diff_threshold, + skip_get_final_text=(lang == "zh"), + tokenizer=tokenizer, + ) + test_results_dict[task_name]["preds"] = predictions + + jiant_evaluate.write_preds( + eval_results_dict=test_results_dict, path=preds_pickle_path, + ) + preds_output_dir = os.path.join(output_dir, "preds", supertask) + os.makedirs(preds_output_dir, exist_ok=True) + for task_name, task_results in test_results_dict.items(): + task = runner.jiant_task_container.task_dict[task_name] + lang = get_qa_language(supertask=supertask, task=task) + py_io.write_json(task_results["preds"], os.path.join(preds_output_dir, f"test-{lang}.json")) + print(f"Wrote {supertask} preds for {len(test_results_dict)} languages") + + +def get_qa_language(supertask: str, task): + """Identify language from QA task""" + if supertask == "mlqa": + assert task.context_language == task.question_language + lang = task.context_language + elif supertask in ["xquad", "tydiqa"]: + lang = task.language + else: + raise KeyError(supertask) + return lang + + +def generate_and_write_preds_for_bucc2018( + runner, output_dir: str, bucc_val_metrics_path: str, skip_if_done: bool = False +): + """Generate predictions (test) for Bucc2018 and write them in XTREME submission format""" + preds_pickle_path = os.path.join(output_dir, "bucc2018_test_preds.p") + if skip_if_done and os.path.exists(preds_pickle_path): + print(f"Skipping cause {preds_pickle_path} exists") + return + else: + print(f"{preds_pickle_path} does not exist") + if bucc_val_metrics_path is None: + # Recompute thresholds: + val_results_dict = runner.run_val( + task_name_list=runner.jiant_task_container.task_run_config.val_task_list, + return_preds=True, + ) + jiant_evaluate.write_preds( + eval_results_dict=val_results_dict, + path=os.path.join(output_dir, "bucc2018_val_preds.p"), + ) + thresholds_dict = { + task_name: task_results["metrics"].minor["best-threshold"] + for task_name, task_results in val_results_dict.items() + } + else: + val_metrics = py_io.read_json(bucc_val_metrics_path) + thresholds_dict = { + task_name: val_metrics[task_name]["metrics"]["minor"]["best-threshold"] + for task_name in runner.jiant_task_container.task_run_config.val_task_list + } + + preds_output_dir = os.path.join(output_dir, "preds", "bucc2018") + os.makedirs(preds_output_dir, exist_ok=True) + test_results_dict = runner.run_test( + task_name_list=runner.jiant_task_container.task_run_config.test_task_list, + ) + jiant_evaluate.write_preds( + eval_results_dict=test_results_dict, path=preds_pickle_path, + ) + for task_name, task_results in test_results_dict.items(): + bitext = bucc2018_lib.bucc_extract( + cand2score=task_results["preds"], th=thresholds_dict[task_name], + ) + lang = runner.jiant_task_container.task_dict[task_name].language + with open(os.path.join(preds_output_dir, f"test-{lang}.tsv"), "w") as f: + for src, trg in bitext: + f.write(f"{src}\t{trg}\n") + print(f"Wrote Bucc2018 preds for {len(test_results_dict)} languages") + + +def generate_and_write_preds_for_tatoeba(runner, output_dir: str, skip_if_done: bool = False): + """Generate predictions (val) for Tateoba and write them in XTREME submission format""" + preds_pickle_path = os.path.join(output_dir, "tatoeba_val_preds.p") + if skip_if_done and os.path.exists(preds_pickle_path): + print(f"Skipping cause {preds_pickle_path} exists") + return + val_results_dict = runner.run_val( + task_name_list=runner.jiant_task_container.task_run_config.val_task_list, return_preds=True, + ) + jiant_evaluate.write_preds( + eval_results_dict=val_results_dict, path=preds_pickle_path, + ) + preds_output_dir = os.path.join(output_dir, "preds", "tatoeba") + os.makedirs(preds_output_dir, exist_ok=True) + for task_name, task_results in val_results_dict.items(): + lang = runner.jiant_task_container.task_dict[task_name].language + with open(os.path.join(preds_output_dir, f"test-{lang}.tsv"), "w") as f: + for idx in task_results["preds"]: + f.write(f"{idx:d}\n") + print(f"Wrote Tatoeba preds for {len(val_results_dict)} languages") + + +def main(): + run_loop(RunConfiguration.default_run_cli()) + + +if __name__ == "__main__": + main() diff --git a/jiant/scripts/download_data/constants.py b/jiant/scripts/download_data/constants.py new file mode 100644 index 000000000..868728a88 --- /dev/null +++ b/jiant/scripts/download_data/constants.py @@ -0,0 +1,11 @@ +# Directly download tasks when nlp format is different than original dataset +SQUAD_TASKS = {"squad_v1", "squad_v2"} +DIRECT_SUPERGLUE_TASKS_TO_DATA_URLS = { + "wsc": f"https://dl.fbaipublicfiles.com/glue/superglue/data/v2/WSC.zip", + "multirc": f"https://dl.fbaipublicfiles.com/glue/superglue/data/v2/MultiRC.zip", + "record": f"https://dl.fbaipublicfiles.com/glue/superglue/data/v2/ReCoRD.zip", +} +OTHER_DOWNLOAD_TASKS = {"abductive_nli", "swag", "qamr", "qasrl"} +DIRECT_DOWNLOAD_TASKS = set( + list(SQUAD_TASKS) + list(DIRECT_SUPERGLUE_TASKS_TO_DATA_URLS) + list(OTHER_DOWNLOAD_TASKS) +) diff --git a/jiant/scripts/download_data/datasets/files_tasks.py b/jiant/scripts/download_data/datasets/files_tasks.py new file mode 100644 index 000000000..537f140ba --- /dev/null +++ b/jiant/scripts/download_data/datasets/files_tasks.py @@ -0,0 +1,224 @@ +import os +import shutil + +import jiant.utils.python.filesystem as filesystem +import jiant.scripts.download_data.utils as download_utils +import jiant.utils.python.io as py_io + +from jiant.scripts.download_data.constants import SQUAD_TASKS, DIRECT_SUPERGLUE_TASKS_TO_DATA_URLS + + +def download_task_data_and_write_config(task_name: str, task_data_path: str, task_config_path: str): + if task_name in SQUAD_TASKS: + download_squad_data_and_write_config( + task_name=task_name, task_data_path=task_data_path, task_config_path=task_config_path + ) + elif task_name in DIRECT_SUPERGLUE_TASKS_TO_DATA_URLS: + download_superglue_data_and_write_config( + task_name=task_name, task_data_path=task_data_path, task_config_path=task_config_path + ) + elif task_name == "abductive_nli": + download_abductive_nli_data_and_write_config( + task_name=task_name, task_data_path=task_data_path, task_config_path=task_config_path + ) + elif task_name == "swag": + download_swag_data_and_write_config( + task_name=task_name, task_data_path=task_data_path, task_config_path=task_config_path + ) + elif task_name == "qamr": + download_qamr_data_and_write_config( + task_name=task_name, task_data_path=task_data_path, task_config_path=task_config_path + ) + elif task_name == "qasrl": + download_qasrl_data_and_write_config( + task_name=task_name, task_data_path=task_data_path, task_config_path=task_config_path + ) + else: + raise KeyError(task_name) + + +def download_squad_data_and_write_config( + task_name: str, task_data_path: str, task_config_path: str +): + if task_name == "squad_v1": + train_file = "train-v1.1.json" + dev_file = "dev-v1.1.json" + version_2_with_negative = False + elif task_name == "squad_v2": + train_file = "train-v2.0.json" + dev_file = "dev-v2.0.json" + version_2_with_negative = True + else: + raise KeyError(task_name) + + os.makedirs(task_data_path, exist_ok=True) + train_path = os.path.join(task_data_path, train_file) + val_path = os.path.join(task_data_path, dev_file) + download_utils.download_file( + url=f"https://rajpurkar.github.io/SQuAD-explorer/dataset/{train_file}", + file_path=train_path, + ) + download_utils.download_file( + url=f"https://rajpurkar.github.io/SQuAD-explorer/dataset/{dev_file}", file_path=val_path, + ) + py_io.write_json( + data={ + "task": "squad", + "paths": {"train": train_path, "val": val_path}, + "version_2_with_negative": version_2_with_negative, + "name": task_name, + }, + path=task_config_path, + ) + + +def download_superglue_data_and_write_config( + task_name: str, task_data_path: str, task_config_path: str +): + # Applies to ReCoRD, MultiRC and WSC + assert task_name not in SQUAD_TASKS + + os.makedirs(task_data_path, exist_ok=True) + download_utils.download_and_unzip( + DIRECT_SUPERGLUE_TASKS_TO_DATA_URLS[task_name], task_data_path + ) + + # Move task data up one folder (nested under task name when unzipped) + # ie: mv ./record/ReCoRD/* ./record + nested_task_dir = os.path.join( + task_data_path, filesystem.find_case_insensitive_filename(task_name, task_data_path) + ) + task_data_files = os.listdir(nested_task_dir) + for f in task_data_files: + # Overwrite file if it exists (overwrite by full path specification) + shutil.move(os.path.join(nested_task_dir, f), os.path.join(task_data_path, f)) + shutil.rmtree(nested_task_dir) + + # Supports datasets with non-standard dev dataset name + if os.path.isfile(os.path.join(task_data_path, "dev.jsonl")): + dev_data_name = "dev.jsonl" + elif os.path.isfile(os.path.join(task_data_path, "val.jsonl")): + dev_data_name = "val.jsonl" + else: + raise RuntimeError("Unsupported dev dataset name in downloaded task.") + + val_path = os.path.join(task_data_path, dev_data_name) + train_path = os.path.join(task_data_path, "train.jsonl") + test_path = os.path.join(task_data_path, "test.jsonl") + py_io.write_json( + data={ + "task": task_name, + "paths": {"train": train_path, "val": val_path, "test": test_path}, + "name": task_name, + }, + path=task_config_path, + ) + + +def download_abductive_nli_data_and_write_config( + task_name: str, task_data_path: str, task_config_path: str +): + os.makedirs(task_data_path, exist_ok=True) + download_utils.download_and_unzip( + "https://storage.googleapis.com/ai2-mosaic/public/alphanli/alphanli-train-dev.zip", + task_data_path, + ) + py_io.write_json( + data={ + "task": task_name, + "paths": { + "train_inputs": os.path.join(task_data_path, "train.jsonl"), + "train_labels": os.path.join(task_data_path, "train-labels.lst"), + "val_inputs": os.path.join(task_data_path, "dev.jsonl"), + "val_labels": os.path.join(task_data_path, "dev-labels.lst"), + }, + "name": task_name, + }, + path=task_config_path, + ) + + +def download_swag_data_and_write_config(task_name: str, task_data_path: str, task_config_path: str): + os.makedirs(task_data_path, exist_ok=True) + download_utils.download_and_unzip( + "https://github.com/rowanz/swagaf/archive/master.zip", task_data_path, + ) + for phase in ["train", "val", "test"]: + os.rename( + os.path.join(task_data_path, "swagaf-master", "data", f"{phase}.csv"), + os.path.join(task_data_path, f"{phase}.csv"), + ) + shutil.rmtree(os.path.join(task_data_path, "swagaf-master")) + py_io.write_json( + data={ + "task": task_name, + "paths": { + "train": os.path.join(task_data_path, "train.csv"), + "val": os.path.join(task_data_path, "val.csv"), + "test": os.path.join(task_data_path, "test.csv"), + }, + "name": task_name, + }, + path=task_config_path, + ) + + +def download_qamr_data_and_write_config(task_name: str, task_data_path: str, task_config_path: str): + os.makedirs(task_data_path, exist_ok=True) + download_utils.download_and_unzip( + "https://github.com/uwnlp/qamr/archive/master.zip", task_data_path, + ) + data_phase_list = ["train", "dev", "test"] + jiant_phase_list = ["train", "val", "test"] + for data_phase, jiant_phase in zip(data_phase_list, jiant_phase_list): + os.rename( + os.path.join(task_data_path, "qamr-master", "data", "filtered", f"{data_phase}.tsv"), + os.path.join(task_data_path, f"{jiant_phase}.tsv"), + ) + os.rename( + os.path.join(task_data_path, "qamr-master", "data", "wiki-sentences.tsv"), + os.path.join(task_data_path, "wiki-sentences.tsv"), + ) + shutil.rmtree(os.path.join(task_data_path, "qamr-master")) + py_io.write_json( + data={ + "task": task_name, + "paths": { + "train": os.path.join(task_data_path, "train.tsv"), + "val": os.path.join(task_data_path, "val.tsv"), + "test": os.path.join(task_data_path, "test.tsv"), + "wiki_dict": os.path.join(task_data_path, "wiki-sentences.tsv"), + }, + "name": task_name, + }, + path=task_config_path, + ) + + +def download_qasrl_data_and_write_config( + task_name: str, task_data_path: str, task_config_path: str +): + os.makedirs(task_data_path, exist_ok=True) + download_utils.download_and_untar( + "http://qasrl.org/data/qasrl-v2.tar", task_data_path, + ) + data_phase_list = ["train", "dev", "test"] + jiant_phase_list = ["train", "val", "test"] + for data_phase, jiant_phase in zip(data_phase_list, jiant_phase_list): + os.rename( + os.path.join(task_data_path, "qasrl-v2", "orig", f"{data_phase}.jsonl.gz"), + os.path.join(task_data_path, f"{jiant_phase}.jsonl.gz"), + ) + shutil.rmtree(os.path.join(task_data_path, "qasrl-v2")) + py_io.write_json( + data={ + "task": task_name, + "paths": { + "train": os.path.join(task_data_path, "train.jsonl.gz"), + "val": os.path.join(task_data_path, "val.jsonl.gz"), + "test": os.path.join(task_data_path, "test.jsonl.gz"), + }, + "name": task_name, + }, + path=task_config_path, + ) diff --git a/jiant/scripts/download_data/datasets/nlp_tasks.py b/jiant/scripts/download_data/datasets/nlp_tasks.py new file mode 100644 index 000000000..8dcdc49ed --- /dev/null +++ b/jiant/scripts/download_data/datasets/nlp_tasks.py @@ -0,0 +1,152 @@ +"""Use this for tasks that can be obtained from NLP without further/special processing""" + +import jiant.scripts.download_data.utils as download_utils +import jiant.utils.python.io as py_io + +# Note to future selves: beware of circular imports when refactoring +from jiant.tasks.retrieval import ( + ColaTask, + MrpcTask, + QnliTask, + QqpTask, + RteTask, + SstTask, + WnliTask, + BoolQTask, + CommitmentBankTask, + WiCTask, + WSCTask, + SuperglueWinogenderDiagnosticsTask, + GlueDiagnosticsTask, +) + + +NLP_CONVERSION_DICT = { + # === GLUE === # + "cola": { + "path": "glue", + "name": "cola", + "field_map": {"sentence": "text"}, + "label_map": ColaTask.ID_TO_LABEL, + }, + "mnli": { + "path": "glue", + "name": "mnli", + "label_map": {0: "entailment", 1: "neutral", 2: "contradiction"}, + "phase_map": {"validation_matched": "val", "test_matched": "test"}, + "phase_list": ["train", "val", "test"], + }, + "mnli_mismatched": { + "path": "glue", + "name": "mnli", + "label_map": {0: "entailment", 1: "neutral", 2: "contradiction"}, + "phase_map": {"validation_mismatched": "val", "test_mismatched": "test"}, + "phase_list": ["val", "test"], + "jiant_task_name": "mnli_mismatched", + }, + "mrpc": { + "path": "glue", + "name": "mrpc", + "field_map": {"sentence1": "text_a", "sentence2": "text_b"}, + "label_map": MrpcTask.ID_TO_LABEL, + }, + "qnli": { + "path": "glue", + "name": "qnli", + "field_map": {"question": "premise", "sentence": "hypothesis"}, + "label_map": QnliTask.ID_TO_LABEL, + }, + "qqp": { + "path": "glue", + "name": "qqp", + "field_map": {"question1": "text_a", "question2": "text_b"}, + "label_map": QqpTask.ID_TO_LABEL, + }, + "rte": { + "path": "glue", + "name": "rte", + "field_map": {"sentence1": "premise", "sentence2": "hypothesis"}, + "label_map": RteTask.ID_TO_LABEL, + }, + "sst": { + "path": "glue", + "name": "sst2", + "field_map": {"sentence": "text"}, + "label_map": SstTask.ID_TO_LABEL, + }, + "stsb": { + "path": "glue", + "name": "stsb", + "field_map": {"sentence1": "text_a", "sentence2": "text_b"}, + }, + "wnli": { + "path": "glue", + "name": "wnli", + "field_map": {"sentence1": "premise", "sentence2": "hypothesis"}, + "label_map": WnliTask.ID_TO_LABEL, + }, + "glue_diagnostics": { + "path": "glue", + "name": "ax", + "label_map": GlueDiagnosticsTask.ID_TO_LABEL, + "phase_map": None, + "jiant_task_name": "glue_diagnostics", + }, + # === SuperGLUE === # + "boolq": {"path": "super_glue", "name": "boolq", "label_map": BoolQTask.ID_TO_LABEL}, + "cb": {"path": "super_glue", "name": "cb", "label_map": CommitmentBankTask.ID_TO_LABEL}, + "copa": {"path": "super_glue", "name": "copa"}, + "multirc": {"path": "super_glue", "name": "multirc"}, + "record": {"path": "super_glue", "name": "record"}, + "wic": {"path": "super_glue", "name": "wic", "label_map": WiCTask.ID_TO_LABEL}, + "wsc": {"path": "super_glue", "name": "wsc.fixed", "label_map": WSCTask.ID_TO_LABEL}, + "superglue_broadcoverage_diagnostics": { + "path": "super_glue", + "name": "axb", + "field_map": {"sentence1": "premise", "sentence2": "hypothesis"}, + "label_map": RteTask.ID_TO_LABEL, + "phase_map": None, + "jiant_task_name": "rte", + }, + "superglue_winogender_diagnostics": { + "path": "super_glue", + "name": "axg", + "label_map": SuperglueWinogenderDiagnosticsTask.ID_TO_LABEL, + "phase_map": None, + "jiant_task_name": "superglue_axg", + }, + # === Other === # + "snli": {"path": "snli", "label_map": {0: "entailment", 1: "neutral", 2: "contradiction"}}, + "commonsenseqa": {"path": "commonsense_qa", "phase_list": ["train", "val", "test"]}, + "hellaswag": { + "path": "hellaswag", + "phase_list": ["train", "val", "test"], + "label_map": {"0": 0, "1": 1, "2": 2, "3": 3}, + }, + "cosmosqa": {"path": "cosmos_qa", "phase_list": ["train", "val", "test"]}, + "socialiqa": {"path": "social_i_qa", "phase_list": ["train", "val"]}, + "scitail": {"path": "scitail", "name": "tsv_format", "phase_list": ["train", "val", "test"]}, +} + +# NLP uses "validation", we use "val" +DEFAULT_PHASE_MAP = {"validation": "val"} + + +def download_data_and_write_config(task_name: str, task_data_path: str, task_config_path: str): + nlp_conversion_metadata = NLP_CONVERSION_DICT[task_name] + examples_dict = download_utils.convert_nlp_dataset_to_examples( + path=nlp_conversion_metadata["path"], + name=nlp_conversion_metadata.get("name"), + field_map=nlp_conversion_metadata.get("field_map"), + label_map=nlp_conversion_metadata.get("label_map"), + phase_map=nlp_conversion_metadata.get("phase_map", DEFAULT_PHASE_MAP), + phase_list=nlp_conversion_metadata.get("phase_list"), + ) + paths_dict = download_utils.write_examples_to_jsonls( + examples_dict=examples_dict, task_data_path=task_data_path, + ) + jiant_task_name = nlp_conversion_metadata.get("jiant_task_name", task_name) + py_io.write_json( + data={"task": jiant_task_name, "paths": paths_dict, "name": task_name}, + path=task_config_path, + ) diff --git a/jiant/scripts/download_data/datasets/xtreme.py b/jiant/scripts/download_data/datasets/xtreme.py new file mode 100644 index 000000000..80f545d85 --- /dev/null +++ b/jiant/scripts/download_data/datasets/xtreme.py @@ -0,0 +1,638 @@ +import copy +import glob +import itertools +import os +import shutil +from pathlib import Path + +import jiant.scripts.download_data.utils as download_utils +import jiant.utils.display as display +import jiant.utils.python.datastructures as datastructures +import jiant.utils.python.io as py_io +import jiant.utils.python.filesystem as filesystem +import jiant.utils.python.strings as strings + + +def download_xnli_data_and_write_config(task_data_base_path: str, task_config_base_path: str): + xnli_temp_path = py_io.create_dir(task_data_base_path, "xnli_temp") + download_utils.download_and_unzip( + "https://dl.fbaipublicfiles.com/XNLI/XNLI-1.0.zip", xnli_temp_path, + ) + full_val_data = py_io.read_jsonl(os.path.join(xnli_temp_path, "XNLI-1.0", "xnli.dev.jsonl")) + val_data = datastructures.group_by(full_val_data, key_func=lambda elem: elem["language"]) + full_test_data = py_io.read_jsonl(os.path.join(xnli_temp_path, "XNLI-1.0", "xnli.test.jsonl")) + test_data = datastructures.group_by(full_test_data, lambda elem: elem["language"]) + languages = sorted(list(val_data)) + for lang in languages: + task_name = f"xnli_{lang}" + task_data_path = py_io.create_dir(task_data_base_path, task_name) + val_path = os.path.join(task_data_path, "val.jsonl") + test_path = os.path.join(task_data_path, "test.jsonl") + py_io.write_jsonl(data=val_data[lang], path=val_path) + py_io.write_jsonl(data=test_data[lang], path=test_path) + py_io.write_json( + data={ + "task": "xnli", + "paths": {"val": val_path, "test": test_path}, + "name": task_name, + "kwargs": {"language": lang}, + }, + path=os.path.join(task_config_base_path, f"{task_name}_config.json"), + ) + shutil.rmtree(xnli_temp_path) + + +def download_pawsx_data_and_write_config(task_data_base_path: str, task_config_base_path: str): + pawsx_temp_path = py_io.create_dir(task_data_base_path, "pawsx_temp") + download_utils.download_and_untar( + "https://storage.googleapis.com/paws/pawsx/x-final.tar.gz", pawsx_temp_path, + ) + languages = sorted(os.listdir(os.path.join(pawsx_temp_path, "x-final"))) + for lang in languages: + task_name = f"pawsx_{lang}" + os.rename( + src=os.path.join(pawsx_temp_path, "x-final", lang), + dst=os.path.join(task_data_base_path, task_name), + ) + paths_dict = { + "val": os.path.join(task_data_base_path, task_name, "dev_2k.tsv"), + "test": os.path.join(task_data_base_path, task_name, "test_2k.tsv"), + } + if lang == "en": + paths_dict["train"] = os.path.join(task_data_base_path, task_name, "train.tsv") + datastructures.set_dict_keys(paths_dict, ["train", "val", "test"]) + py_io.write_json( + data={ + "task": "pawsx", + "paths": paths_dict, + "name": task_name, + "kwargs": {"language": lang}, + }, + path=os.path.join(task_config_base_path, f"{task_name}_config.json"), + ) + shutil.rmtree(pawsx_temp_path) + + +def download_udpos_data_and_write_config(task_data_base_path: str, task_config_base_path: str): + # UDPOS requires networkx==1.11 + + def _read_one_file(file): + # Adapted from https://github.com/JunjieHu/xtreme/blob/ + # 9fe0b142d0ee3eb7dd047ab86f12a76702e79bb4/utils_preprocess.py + data = [] + sent, tag, lines = [], [], [] + for line in open(file, "r"): + items = line.strip().split("\t") + if len(items) != 10: + num_empty = sum([int(w == "_") for w in sent]) + if num_empty == 0 or num_empty < len(sent) - 1: + data.append((sent, tag, lines)) + sent, tag, lines = [], [], [] + else: + sent.append(items[1].strip()) + tag.append(items[3].strip()) + lines.append(line.strip()) + assert len(sent) == int(items[0]), "line={}, sent={}, tag={}".format( + line, sent, tag + ) + return data + + def _remove_empty_space(data): + # Adapted from https://github.com/google-research/xtreme/blob/ + # 522434d1aece34131d997a97ce7e9242a51a688a/utils_preprocess.py#L212 + new_data = {} + for split in data: + new_data[split] = [] + for sent, tag, lines in data[split]: + new_sent = ["".join(w.replace("\u200c", "").split(" ")) for w in sent] + lines = [line.replace("\u200c", "") for line in lines] + assert len(" ".join(new_sent).split(" ")) == len(tag) + new_data[split].append((new_sent, tag, lines)) + return new_data + + def check_file(file): + # Adapted from https://github.com/google-research/xtreme/blob/ + # 522434d1aece34131d997a97ce7e9242a51a688a/utils_preprocess.py#L223 + for i, l in enumerate(open(file)): + items = l.strip().split("\t") + assert len(items[0].split(" ")) == len(items[1].split(" ")), "idx={}, line={}".format( + i, l + ) + + def _write_files(data, output_dir, lang_, suffix): + # Adapted from https://github.com/google-research/xtreme/blob/ + # 522434d1aece34131d997a97ce7e9242a51a688a/utils_preprocess.py#L228 + for split in data: + if len(data[split]) > 0: + prefix = os.path.join(output_dir, f"{split}-{lang_}") + if suffix == "mt": + with open(prefix + ".mt.tsv", "w") as fout: + for idx, (sent, tag, _) in enumerate(data[split]): + newline = "\n" if idx != len(data[split]) - 1 else "" + fout.write("{}\t{}{}".format(" ".join(sent), " ".join(tag), newline)) + check_file(prefix + ".mt.tsv") + print(" - finish checking " + prefix + ".mt.tsv") + elif suffix == "tsv": + with open(prefix + ".tsv", "w") as fout: + for sidx, (sent, tag, _) in enumerate(data[split]): + for widx, (w, t) in enumerate(zip(sent, tag)): + newline = ( + "" + if (sidx == len(data[split]) - 1) and (widx == len(sent) - 1) + else "\n" + ) + fout.write("{}\t{}{}".format(w, t, newline)) + fout.write("\n") + elif suffix == "conll": + with open(prefix + ".conll", "w") as fout: + for _, _, lines in data[split]: + for line in lines: + fout.write(line.strip() + "\n") + fout.write("\n") + print(f"finish writing file to {prefix}.{suffix}") + + languages = ( + "af ar bg de el en es et eu fa fi fr he hi hu id it ja " + "kk ko mr nl pt ru ta te th tl tr ur vi yo zh" + ).split() + udpos_temp_path = py_io.create_dir(task_data_base_path, "udpos_temp") + download_utils.download_and_untar( + "https://lindat.mff.cuni.cz/repository/xmlui/bitstream/handle/11234/1-3105/" + "ud-treebanks-v2.5.tgz", + udpos_temp_path, + ) + download_utils.download_file( + "https://raw.githubusercontent.com/google-research/xtreme/master/third_party/" + "ud-conversion-tools/lib/conll.py", + os.path.join(udpos_temp_path, "conll.py"), + ) + conll = filesystem.import_from_path(os.path.join(udpos_temp_path, "conll.py")) + conllu_path_ls = sorted(glob.glob(os.path.join(udpos_temp_path, "*", "*", "*.conllu"))) + conll_path = os.path.join(udpos_temp_path, "conll") + + # === Convert conllu files to conll === # + for input_path in display.tqdm(conllu_path_ls, desc="Convert conllu files to conll format"): + input_path_fol, input_path_file = os.path.split(input_path) + lang = input_path_file.split("_")[0] + os.makedirs(os.path.join(conll_path, lang), exist_ok=True) + output_path = os.path.join( + conll_path, lang, strings.replace_suffix(input_path_file, "conllu", "conll") + ) + pos_rank_precedence_dict = { + "default": ( + "VERB NOUN PROPN PRON ADJ NUM ADV INTJ AUX ADP DET PART CCONJ SCONJ X PUNCT" + ).split(" "), + "es": "VERB AUX PRON ADP DET".split(" "), + "fr": "VERB AUX PRON NOUN ADJ ADV ADP DET PART SCONJ CONJ".split(" "), + "it": "VERB AUX ADV PRON ADP DET INTJ".split(" "), + } + + if lang in pos_rank_precedence_dict: + current_pos_precedence_list = pos_rank_precedence_dict[lang] + else: + current_pos_precedence_list = pos_rank_precedence_dict["default"] + + cio = conll.CoNLLReader() + orig_treebank = cio.read_conll_u(input_path) + modif_treebank = copy.copy(orig_treebank) + + for s in modif_treebank: + s.filter_sentence_content( + replace_subtokens_with_fused_forms=True, + posPreferenceDict=current_pos_precedence_list, + node_properties_to_remove=False, + remove_deprel_suffixes=False, + remove_arabic_diacritics=False, + ) + + cio.write_conll( + list_of_graphs=modif_treebank, + conll_path=Path(output_path), + conllformat="conll2006", + print_fused_forms=True, + print_comments=False, + ) + + # === Convert conll to final format === # + for lang in display.tqdm(languages, desc="Convert conll to final format"): + task_name = f"udpos_{lang}" + task_data_path = os.path.join(task_data_base_path, task_name) + os.makedirs(task_data_path, exist_ok=True) + all_examples = {k: [] for k in ["train", "val", "test"]} + for path in sorted(glob.glob(os.path.join(conll_path, lang, "*.conll"))): + examples = _read_one_file(path) + if "train" in path: + all_examples["train"] += examples + elif "dev" in path: + all_examples["val"] += examples + elif "test" in path: + all_examples["test"] += examples + else: + raise KeyError() + all_examples = _remove_empty_space(all_examples) + _write_files( + data=all_examples, output_dir=task_data_path, lang_=lang, suffix="tsv", + ) + paths_dict = { + phase: os.path.join(task_data_path, f"{phase}-{lang}.tsv") + for phase, phase_data in all_examples.items() + if len(phase_data) > 0 + } + py_io.write_json( + data={ + "task": "udpos", + "paths": paths_dict, + "name": task_name, + "kwargs": {"language": lang}, + }, + path=os.path.join(task_config_base_path, f"{task_name}_config.json"), + ) + shutil.rmtree(udpos_temp_path) + + +def download_panx_data_and_write_config(task_data_base_path: str, task_config_base_path: str): + def _process_one_file(infile, outfile): + lines = open(infile, "r").readlines() + if lines[-1].strip() == "": + lines = lines[:-1] + with open(outfile, "w") as fout: + for line in lines: + items = line.strip().split("\t") + if len(items) == 2: + label = items[1].strip() + idx = items[0].find(":") + if idx != -1: + token = items[0][idx + 1 :].strip() + fout.write(f"{token}\t{label}\n") + else: + fout.write("\n") + + panx_temp_path = os.path.join(task_data_base_path, "panx_temp") + zip_path = os.path.join(panx_temp_path, "AmazonPhotos.zip") + assert os.path.exists(zip_path), ( + "Download AmazonPhotos.zip from" + " https://www.amazon.com/clouddrive/share/d3KGCRCIYwhKJF0H3eWA26hjg2ZCRhjpEQtDL70FSBN" + f" and save it to {zip_path}" + ) + download_utils.unzip_file(zip_path=zip_path, extract_location=panx_temp_path) + languages = ( + "af ar bg bn de el en es et eu fa fi fr he hi hu id it ja jv ka " + "kk ko ml mr ms my nl pt ru sw ta te th tl tr ur vi yo zh" + ).split() + for lang in languages: + task_name = f"panx_{lang}" + untar_path = os.path.join(panx_temp_path, "panx_dataset", lang) + os.makedirs(untar_path, exist_ok=True) + download_utils.untar_file( + tar_path=os.path.join(panx_temp_path, "panx_dataset", f"{lang}.tar.gz"), + extract_location=untar_path, + delete=True, + ) + task_data_path = os.path.join(task_data_base_path, task_name) + os.makedirs(task_data_path, exist_ok=True) + filename_dict = {"train": "train", "val": "dev", "test": "test"} + paths_dict = {} + for phase, filename in filename_dict.items(): + in_path = os.path.join(untar_path, filename) + out_path = os.path.join(task_data_path, f"{phase}.tsv") + if not os.path.exists(in_path): + continue + _process_one_file(infile=in_path, outfile=out_path) + paths_dict[phase] = out_path + py_io.write_json( + data={ + "task": "panx", + "paths": paths_dict, + "name": task_name, + "kwargs": {"language": lang}, + }, + path=os.path.join(task_config_base_path, f"{task_name}_config.json"), + ) + shutil.rmtree(os.path.join(panx_temp_path, "panx_dataset")) + + +def download_xquad_data_and_write_config(task_data_base_path: str, task_config_base_path: str): + languages = "ar de el en es hi ru th tr vi zh".split() + for lang in languages: + task_name = f"xquad_{lang}" + task_data_path = py_io.create_dir(task_data_base_path, task_name) + path = os.path.join(task_data_path, "xquad.json") + download_utils.download_file( + url=f"https://raw.githubusercontent.com/deepmind/xquad/master/xquad.{lang}.json", + file_path=path, + ) + py_io.write_json( + data={ + "task": "xquad", + "paths": {"val": path}, + "name": task_name, + "kwargs": {"language": lang}, + }, + path=os.path.join(task_config_base_path, f"{task_name}_config.json"), + ) + + +def download_mlqa_data_and_write_config(task_data_base_path: str, task_config_base_path: str): + mlqa_temp_path = py_io.create_dir(task_data_base_path, "mlqa_temp") + download_utils.download_and_unzip( + "https://dl.fbaipublicfiles.com/MLQA/MLQA_V1.zip", mlqa_temp_path, + ) + languages = "ar de en es hi vi zh".split() + for lang1, lang2 in itertools.product(languages, languages): + task_name = f"mlqa_{lang1}_{lang2}" + task_data_path = py_io.create_dir(task_data_base_path, task_name) + val_path = os.path.join(task_data_path, f"dev-context-{lang1}-question-{lang2}.json") + os.rename( + src=os.path.join( + mlqa_temp_path, "MLQA_V1", "dev", f"dev-context-{lang1}-question-{lang2}.json" + ), + dst=val_path, + ) + test_path = os.path.join(task_data_path, f"test-context-{lang1}-question-{lang2}.json") + os.rename( + src=os.path.join( + mlqa_temp_path, "MLQA_V1", "test", f"test-context-{lang1}-question-{lang2}.json" + ), + dst=test_path, + ) + py_io.write_json( + data={ + "task": "mlqa", + "paths": {"val": val_path, "test": test_path}, + "kwargs": {"context_language": lang1, "question_language": lang2}, + "name": task_name, + }, + path=os.path.join(task_config_base_path, f"{task_name}_config.json"), + ) + shutil.rmtree(mlqa_temp_path) + + +def download_tydiqa_data_and_write_config(task_data_base_path: str, task_config_base_path: str): + tydiqa_temp_path = py_io.create_dir(task_data_base_path, "tydiqa_temp") + full_train_path = os.path.join(tydiqa_temp_path, "tydiqa-goldp-v1.1-train.json") + download_utils.download_file( + "https://storage.googleapis.com/tydiqa/v1.1/tydiqa-goldp-v1.1-train.json", full_train_path, + ) + download_utils.download_and_untar( + "https://storage.googleapis.com/tydiqa/v1.1/tydiqa-goldp-v1.1-dev.tgz", tydiqa_temp_path, + ) + languages_dict = { + "arabic": "ar", + "bengali": "bn", + "english": "en", + "finnish": "fi", + "indonesian": "id", + "korean": "ko", + "russian": "ru", + "swahili": "sw", + "telugu": "te", + } + + # Split train data + data = py_io.read_json(full_train_path) + lang2data = {lang: [] for lang in languages_dict.values()} + for doc in data["data"]: + for par in doc["paragraphs"]: + context = par["context"] + for qa in par["qas"]: + question = qa["question"] + question_id = qa["id"] + example_lang = languages_dict[question_id.split("-")[0]] + q_id = question_id.split("-")[-1] + for answer in qa["answers"]: + a_start, a_text = answer["answer_start"], answer["text"] + a_end = a_start + len(a_text) + assert context[a_start:a_end] == a_text + lang2data[example_lang].append( + { + "paragraphs": [ + { + "context": context, + "qas": [ + {"answers": qa["answers"], "question": question, "id": q_id} + ], + } + ] + } + ) + + for full_lang, lang in languages_dict.items(): + task_name = f"tydiqa_{lang}" + task_data_path = py_io.create_dir(task_data_base_path, task_name) + train_path = os.path.join(task_data_path, f"tydiqa.{lang}.train.json") + py_io.write_json( + data=data, path=train_path, + ) + val_path = os.path.join(task_data_path, f"tydiqa.{lang}.dev.json") + os.rename( + src=os.path.join( + tydiqa_temp_path, "tydiqa-goldp-v1.1-dev", f"tydiqa-goldp-dev-{full_lang}.json" + ), + dst=val_path, + ) + py_io.write_json( + data={ + "task": "tydiqa", + "paths": {"train": train_path, "val": val_path}, + "kwargs": {"language": lang}, + "name": task_name, + }, + path=os.path.join(task_config_base_path, f"{task_name}_config.json"), + ) + shutil.rmtree(tydiqa_temp_path) + + +def download_bucc2018_data_and_write_config(task_data_base_path: str, task_config_base_path: str): + bucc2018_temp_path = py_io.create_dir(task_data_base_path, "bucc_temp") + languages = "de fr ru zh".split() + for lang in languages: + download_utils.download_and_untar( + f"https://comparable.limsi.fr/bucc2018/bucc2018-{lang}-en.training-gold.tar.bz2", + bucc2018_temp_path, + ) + download_utils.download_and_untar( + f"https://comparable.limsi.fr/bucc2018/bucc2018-{lang}-en.sample-gold.tar.bz2", + bucc2018_temp_path, + ) + for lang in languages: + task_name = f"bucc2018_{lang}" + task_data_path = py_io.create_dir(task_data_base_path, task_name) + val_eng_path = os.path.join(task_data_path, f"{lang}-en.dev.en") + val_other_path = os.path.join(task_data_path, f"{lang}-en.dev.{lang}") + val_labels_path = os.path.join(task_data_path, f"{lang}-en.dev.gold") + test_eng_path = os.path.join(task_data_path, f"{lang}-en.test.en") + test_other_path = os.path.join(task_data_path, f"{lang}-en.test.{lang}") + # sample -> dev + # training -> test (yup, it's weird) + os.rename( + src=os.path.join(bucc2018_temp_path, "bucc2018", f"{lang}-en", f"{lang}-en.sample.en"), + dst=val_eng_path, + ) + os.rename( + src=os.path.join( + bucc2018_temp_path, "bucc2018", f"{lang}-en", f"{lang}-en.sample.{lang}" + ), + dst=val_other_path, + ) + os.rename( + src=os.path.join( + bucc2018_temp_path, "bucc2018", f"{lang}-en", f"{lang}-en.sample.gold" + ), + dst=val_labels_path, + ) + os.rename( + src=os.path.join( + bucc2018_temp_path, "bucc2018", f"{lang}-en", f"{lang}-en.training.en" + ), + dst=test_eng_path, + ) + os.rename( + src=os.path.join( + bucc2018_temp_path, "bucc2018", f"{lang}-en", f"{lang}-en.training.{lang}" + ), + dst=test_other_path, + ) + py_io.write_json( + data={ + "task": "bucc2018", + "paths": { + "val": { + "eng": val_eng_path, + "other": val_other_path, + "labels": val_labels_path, + }, + "test": {"eng": test_eng_path, "other": test_other_path}, + }, + "kwargs": {"language": lang}, + "name": task_name, + }, + path=os.path.join(task_config_base_path, f"{task_name}_config.json"), + ) + shutil.rmtree(bucc2018_temp_path) + + +def download_tatoeba_data_and_write_config(task_data_base_path: str, task_config_base_path: str): + tatoeba_temp_path = py_io.create_dir(task_data_base_path, "tatoeba_temp") + download_utils.download_and_unzip( + "https://github.com/facebookresearch/LASER/archive/master.zip", tatoeba_temp_path, + ) + languages_dict = { + "afr": "af", + "ara": "ar", + "bul": "bg", + "ben": "bn", + "deu": "de", + "ell": "el", + "spa": "es", + "est": "et", + "eus": "eu", + "pes": "fa", + "fin": "fi", + "fra": "fr", + "heb": "he", + "hin": "hi", + "hun": "hu", + "ind": "id", + "ita": "it", + "jpn": "ja", + "jav": "jv", + "kat": "ka", + "kaz": "kk", + "kor": "ko", + "mal": "ml", + "mar": "mr", + "nld": "nl", + "por": "pt", + "rus": "ru", + "swh": "sw", + "tam": "ta", + "tel": "te", + "tha": "th", + "tgl": "tl", + "tur": "tr", + "urd": "ur", + "vie": "vi", + "cmn": "zh", + "eng": "en", + } + raw_base_path = os.path.join(tatoeba_temp_path, "LASER-master", "data", "tatoeba", "v1") + for full_lang, lang in languages_dict.items(): + task_name = f"tatoeba_{lang}" + if lang == "en": + continue + task_data_path = py_io.create_dir(task_data_base_path, task_name) + eng_src = os.path.join(raw_base_path, f"tatoeba.{full_lang}-eng.eng") + other_src = os.path.join(raw_base_path, f"tatoeba.{full_lang}-eng.{full_lang}") + eng_out = os.path.join(task_data_path, f"{lang}-en.en") + other_out = os.path.join(task_data_path, f"{lang}-en.{lang}") + labels_out = os.path.join(task_data_path, f"{lang}-en.labels") + tgts = [line.strip() for line in py_io.read_file_lines(eng_src)] + os.rename(src=other_src, dst=other_out) + idx = range(len(tgts)) + data = zip(tgts, idx) + + # Tatoeba is a retrieval dataset where you have a set of sentences in English and another + # set in another language, and you need to match them. It also doesn't have training + # data, so it's pretty much evaluation only. However, the dataset is distributed with the + # sentences in order, i.e. the retrieval pairing is the sentence order. + # + # The XTREME authors intentionally scramble the order by sorting one of the two + # sets alphabetically. We're following their recipe, but also retaining the labels for + # internal scoring. + with open(eng_out, "w") as ftgt, open(labels_out, "w") as flabels: + for t, i in sorted(data, key=lambda x: x[0]): + ftgt.write(f"{t}\n") + flabels.write(f"{i}\n") + py_io.write_json( + data={ + "task": "tatoeba", + "paths": {"eng": eng_out, "other": other_out, "labels_path": labels_out}, + "kwargs": {"language": lang}, + "name": task_name, + }, + path=os.path.join(task_config_base_path, f"{task_name}_config.json"), + ) + shutil.rmtree(tatoeba_temp_path) + + +def download_xtreme_data_and_write_config( + task_name: str, task_data_base_path: str, task_config_base_path: str +): + if task_name == "xnli": + download_xnli_data_and_write_config( + task_data_base_path=task_data_base_path, task_config_base_path=task_config_base_path, + ) + elif task_name == "pawsx": + download_pawsx_data_and_write_config( + task_data_base_path=task_data_base_path, task_config_base_path=task_config_base_path, + ) + elif task_name == "udpos": + download_udpos_data_and_write_config( + task_data_base_path=task_data_base_path, task_config_base_path=task_config_base_path, + ) + elif task_name == "panx": + download_panx_data_and_write_config( + task_data_base_path=task_data_base_path, task_config_base_path=task_config_base_path, + ) + elif task_name == "xquad": + download_xquad_data_and_write_config( + task_data_base_path=task_data_base_path, task_config_base_path=task_config_base_path, + ) + elif task_name == "mlqa": + download_mlqa_data_and_write_config( + task_data_base_path=task_data_base_path, task_config_base_path=task_config_base_path, + ) + elif task_name == "tydiqa": + download_tydiqa_data_and_write_config( + task_data_base_path=task_data_base_path, task_config_base_path=task_config_base_path, + ) + elif task_name == "bucc2018": + download_bucc2018_data_and_write_config( + task_data_base_path=task_data_base_path, task_config_base_path=task_config_base_path, + ) + elif task_name == "tatoeba": + download_tatoeba_data_and_write_config( + task_data_base_path=task_data_base_path, task_config_base_path=task_config_base_path, + ) + else: + raise KeyError(task_name) diff --git a/jiant/scripts/download_data/runscript.py b/jiant/scripts/download_data/runscript.py new file mode 100644 index 000000000..f11d64cb8 --- /dev/null +++ b/jiant/scripts/download_data/runscript.py @@ -0,0 +1,97 @@ +import os +import argparse + +import jiant.utils.python.io as py_io +import jiant.scripts.download_data.datasets.nlp_tasks as nlp_tasks_download +import jiant.scripts.download_data.datasets.xtreme as xtreme_download +import jiant.scripts.download_data.datasets.files_tasks as files_tasks_download +from jiant.tasks.constants import ( + GLUE_TASKS, + SUPERGLUE_TASKS, + OTHER_NLP_TASKS, + XTREME_TASKS, + BENCHMARKS, +) +from jiant.scripts.download_data.constants import SQUAD_TASKS, DIRECT_DOWNLOAD_TASKS + +# DIRECT_DOWNLOAD_TASKS need to be directly downloaded because the nlp +# implementation differs from the original dataset format +NLP_DOWNLOADER_TASKS = GLUE_TASKS | SUPERGLUE_TASKS | OTHER_NLP_TASKS - DIRECT_DOWNLOAD_TASKS +SUPPORTED_TASKS = NLP_DOWNLOADER_TASKS | XTREME_TASKS | SQUAD_TASKS | DIRECT_DOWNLOAD_TASKS + + +# noinspection PyUnusedLocal +def list_supported_tasks_cli(args): + print("Supported tasks:") + for task in sorted(list(SUPPORTED_TASKS)): + print(task) + + +def download_data_cli(args): + output_base_path = args.output_path + if args.tasks: + task_names = args.tasks + elif args.benchmark: + task_names = BENCHMARKS[args.benchmark] + else: + raise RuntimeError() + download_data( + task_names=task_names, output_base_path=output_base_path, + ) + + +def download_data(task_names, output_base_path): + task_data_base_path = py_io.create_dir(output_base_path, "data") + task_config_base_path = py_io.create_dir(output_base_path, "configs") + + assert set(task_names).issubset(SUPPORTED_TASKS) + + # Download specified tasks and generate configs for specified tasks + for i, task_name in enumerate(task_names): + task_data_path = os.path.join(task_data_base_path, task_name) + + if task_name in NLP_DOWNLOADER_TASKS: + nlp_tasks_download.download_data_and_write_config( + task_name=task_name, + task_data_path=task_data_path, + task_config_path=os.path.join(task_config_base_path, f"{task_name}_config.json"), + ) + elif task_name in XTREME_TASKS: + xtreme_download.download_xtreme_data_and_write_config( + task_name=task_name, + task_data_base_path=task_data_base_path, + task_config_base_path=task_config_base_path, + ) + elif task_name in DIRECT_DOWNLOAD_TASKS: + files_tasks_download.download_task_data_and_write_config( + task_name=task_name, + task_data_path=task_data_path, + task_config_path=os.path.join(task_config_base_path, f"{task_name}_config.json"), + ) + else: + raise KeyError() + print(f"Downloaded and generated configs for '{task_name}' ({i+1}/{len(task_names)})") + + +def main(): + parser = argparse.ArgumentParser(description="Download NLP datasets and generate task configs") + subparsers = parser.add_subparsers() + sp_list = subparsers.add_parser("list", help="list supported tasks in downloader") + sp_download = subparsers.add_parser("download", help="download data command") + sp_download.add_argument( + "--output_path", required=True, help="base output path for downloaded data and task configs" + ) + sp_download_group = sp_download.add_mutually_exclusive_group(required=True) + sp_download_group.add_argument("--tasks", nargs="+", help="list of tasks to download") + sp_download_group.add_argument("--benchmark", choices=BENCHMARKS) + + # Hook subparsers up to functions + sp_list.set_defaults(func=list_supported_tasks_cli) + sp_download.set_defaults(func=download_data_cli) + + args = parser.parse_args() + args.func(args) + + +if __name__ == "__main__": + main() diff --git a/jiant/scripts/download_data/utils.py b/jiant/scripts/download_data/utils.py new file mode 100644 index 000000000..2bcb3d895 --- /dev/null +++ b/jiant/scripts/download_data/utils.py @@ -0,0 +1,101 @@ +import nlp +import os +import tarfile +import urllib +import zipfile + +import jiant.utils.python.io as py_io +from jiant.utils.python.datastructures import replace_key + + +def convert_nlp_dataset_to_examples( + path, name=None, version=None, field_map=None, label_map=None, phase_map=None, phase_list=None +): + """Helper function for reading from nlp.load_dataset and converting to examples + + Args: + path: path argument (from nlp.load_dataset) + name: name argument (from nlp.load_dataset) + version: version argument (from nlp.load_dataset) + field_map: dictionary for renaming fields, non-exhaustive + label_map: dictionary for replacing labels, non-exhaustive + phase_map: dictionary for replacing phase names, non-exhaustive + phase_list: phases to keep (after phase_map) + + Returns: + Dict[phase] -> list[examples] + """ + dataset = nlp.load_dataset(path=path, name=name, version=version) + if phase_map: + for old_phase_name, new_phase_name in phase_map.items(): + replace_key(dataset, old_key=old_phase_name, new_key=new_phase_name) + if phase_list is None: + phase_list = dataset.keys() + examples_dict = {} + for phase in phase_list: + phase_examples = [] + for raw_example in dataset[phase]: + if field_map: + for old_field_name, new_field_name in field_map.items(): + replace_key(raw_example, old_key=old_field_name, new_key=new_field_name) + if label_map and "label" in raw_example: + # Optionally use an dict or function to map labels + label = raw_example["label"] + if isinstance(label_map, dict): + if raw_example["label"] in label_map: + label = label_map[raw_example["label"]] + elif callable(label_map): + label = label_map(raw_example["label"]) + else: + raise TypeError(label_map) + raw_example["label"] = label + phase_examples.append(raw_example) + examples_dict[phase] = phase_examples + return examples_dict + + +def write_examples_to_jsonls(examples_dict, task_data_path): + os.makedirs(task_data_path, exist_ok=True) + paths_dict = {} + for phase, example_list in examples_dict.items(): + jsonl_path = os.path.join(task_data_path, f"{phase}.jsonl") + py_io.write_jsonl(example_list, jsonl_path) + paths_dict[phase] = jsonl_path + return paths_dict + + +def download_and_unzip(url, extract_location): + """Downloads and unzips a file, and deletes the zip after""" + _, file_name = os.path.split(url) + zip_path = os.path.join(extract_location, file_name) + download_file(url=url, file_path=zip_path) + unzip_file(zip_path=zip_path, extract_location=extract_location, delete=True) + + +def unzip_file(zip_path, extract_location, delete=False): + """Unzip a file, optionally deleting after""" + with zipfile.ZipFile(zip_path) as zip_ref: + zip_ref.extractall(extract_location) + if delete: + os.remove(zip_path) + + +def download_and_untar(url, extract_location): + """Downloads and untars a file, and deletes the tar after""" + _, file_name = os.path.split(url) + tar_path = os.path.join(extract_location, file_name) + download_file(url, tar_path) + untar_file(tar_path=tar_path, extract_location=extract_location, delete=True) + + +def untar_file(tar_path, extract_location, delete=False): + """Untars a file, optionally deleting after""" + with tarfile.open(tar_path) as tar: + tar.extractall(path=extract_location) + if delete: + os.remove(tar_path) + + +def download_file(url, file_path): + # noinspection PyUnresolvedReferences + urllib.request.urlretrieve(url, file_path) diff --git a/jiant/scripts/preproc/__init__.py b/jiant/scripts/preproc/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/jiant/scripts/preproc/export_glue_data.py b/jiant/scripts/preproc/export_glue_data.py new file mode 100644 index 000000000..27d7733c3 --- /dev/null +++ b/jiant/scripts/preproc/export_glue_data.py @@ -0,0 +1,213 @@ +import csv +import os +import tqdm + +import jiant.utils.python.io as py_io +import jiant.utils.zconf as zconf + + +GLUE_CONVERSION = { + "cola": { + "data": { + "train": {"cols": {"text": 3, "label": 1}}, + "val": {"cols": {"text": 3, "label": 1}, "meta": {"filename": "dev"}}, + "test": {"cols": {"text": 1}, "meta": {"skiprows": 1}}, + }, + "dir_name": "CoLA", + }, + "mnli": { + "data": { + "train": { + "cols": {"premise": 8, "hypothesis": 9, "label": 11}, + "meta": {"skiprows": 1}, + }, + "val": { + "cols": {"premise": 8, "hypothesis": 9, "label": 15}, + "meta": {"filename": "dev_matched", "skiprows": 1}, + }, + "val_mismatched": { + "cols": {"premise": 8, "hypothesis": 9, "label": 15}, + "meta": {"filename": "dev_mismatched", "skiprows": 1}, + }, + "test": { + "cols": {"premise": 8, "hypothesis": 9}, + "meta": {"filename": "test_matched", "skiprows": 1}, + }, + "test_mismatched": { + "cols": {"premise": 8, "hypothesis": 9}, + "meta": {"filename": "test_mismatched", "skiprows": 1}, + }, + }, + "dir_name": "MNLI", + }, + "mrpc": { + "data": { + "train": {"cols": {"text_a": 3, "text_b": 4, "label": 0}, "meta": {"skiprows": 1}}, + "val": { + "cols": {"text_a": 3, "text_b": 4, "label": 0}, + "meta": {"filename": "dev", "skiprows": 1}, + }, + "test": {"cols": {"text_a": 3, "text_b": 4}, "meta": {"skiprows": 1}}, + }, + "dir_name": "MRPC", + }, + "qnli": { + "data": { + "train": {"cols": {"premise": 1, "hypothesis": 2, "label": 3}, "meta": {"skiprows": 1}}, + "val": { + "cols": {"premise": 1, "hypothesis": 2, "label": 3}, + "meta": {"filename": "dev", "skiprows": 1}, + }, + "test": {"cols": {"premise": 1, "hypothesis": 2}, "meta": {"skiprows": 1}}, + }, + "dir_name": "QNLI", + }, + "qqp": { + "data": { + "train": {"cols": {"text_a": 3, "text_b": 4, "label": 5}, "meta": {"skiprows": 1}}, + "val": { + "cols": {"text_a": 3, "text_b": 4, "label": 5}, + "meta": {"filename": "dev", "skiprows": 1}, + }, + "test": {"cols": {"text_a": 1, "text_b": 2}, "meta": {"skiprows": 1}}, + }, + "dir_name": "QQP", + }, + "rte": { + "data": { + "train": {"cols": {"premise": 1, "hypothesis": 2, "label": 3}, "meta": {"skiprows": 1}}, + "val": { + "cols": {"premise": 1, "hypothesis": 2, "label": 3}, + "meta": {"filename": "dev", "skiprows": 1}, + }, + "test": {"cols": {"premise": 1, "hypothesis": 2}, "meta": {"skiprows": 1}}, + }, + "dir_name": "RTE", + }, + "sst": { + "data": { + "train": {"cols": {"text": 0, "label": 1}, "meta": {"skiprows": 1}}, + "val": {"cols": {"text": 0, "label": 1}, "meta": {"filename": "dev", "skiprows": 1}}, + "test": {"cols": {"text": 1}, "meta": {"skiprows": 1}}, + }, + "dir_name": "SST-2", + }, + "stsb": { + "data": { + "train": {"cols": {"text_a": 7, "text_b": 8, "label": 9}, "meta": {"skiprows": 1}}, + "val": { + "cols": {"text_a": 7, "text_b": 8, "label": 9}, + "meta": {"filename": "dev", "skiprows": 1}, + }, + "test": {"cols": {"text_a": 7, "text_b": 8}, "meta": {"skiprows": 1}}, + }, + "dir_name": "STS-B", + }, + "wnli": { + "data": { + "train": {"cols": {"premise": 1, "hypothesis": 2, "label": 3}, "meta": {"skiprows": 1}}, + "val": { + "cols": {"premise": 1, "hypothesis": 2, "label": 3}, + "meta": {"filename": "dev", "skiprows": 1}, + }, + "test": {"cols": {"premise": 1, "hypothesis": 2}, "meta": {"skiprows": 1}}, + }, + "dir_name": "WNLI", + }, + "glue_diagnostic": { + "data": { + "test": { + "cols": {"premise": 1, "hypothesis": 2}, + "meta": {"filename": "diagnostic", "skiprows": 1}, + }, + }, + "dir_name": "diagnostic", + }, +} + + +def read_tsv(input_file, quotechar=None, skiprows=None): + """Reads a tab separated value file.""" + with open(input_file, "r", encoding="utf-8-sig") as f: + result = list(csv.reader(f, delimiter="\t", quotechar=quotechar)) + if skiprows: + result = result[skiprows:] + return result + + +def get_full_examples(task_name, input_base_path): + task_metadata = GLUE_CONVERSION[task_name] + all_examples = {} + for phase, phase_config in task_metadata["data"].items(): + meta_dict = phase_config.get("meta", {}) + filename = meta_dict.get("filename", phase) + rows = read_tsv( + os.path.join(input_base_path, task_metadata["dir_name"], f"{filename}.tsv"), + skiprows=meta_dict.get("skiprows"), + ) + examples = [] + for row in rows: + try: + example = {} + for col, i in phase_config["cols"].items(): + example[col] = row[i] + examples.append(example) + except IndexError: + if task_name == "qqp": + continue + all_examples[phase] = examples + return all_examples + + +def convert_glue_data(input_base_path, task_data_path, task_name): + os.makedirs(task_data_path, exist_ok=True) + task_all_examples = get_full_examples(task_name=task_name, input_base_path=input_base_path) + paths_dict = {} + for phase, phase_data in task_all_examples.items(): + phase_data_path = os.path.join(task_data_path, f"{phase}.jsonl") + py_io.write_jsonl( + data=phase_data, path=phase_data_path, + ) + paths_dict[phase] = phase_data_path + return paths_dict + + +def preprocess_all_glue_data(input_base_path, output_base_path, task_name_ls=None): + if task_name_ls is None: + task_name_ls = GLUE_CONVERSION.keys() + os.makedirs(output_base_path, exist_ok=True) + os.makedirs(os.path.join(output_base_path, "data"), exist_ok=True) + os.makedirs(os.path.join(output_base_path, "configs"), exist_ok=True) + for task_name in tqdm.tqdm(task_name_ls): + task_data_path = os.path.join(output_base_path, "data", task_name) + paths_dict = convert_glue_data( + input_base_path=input_base_path, task_data_path=task_data_path, task_name=task_name, + ) + config = {"task": task_name, "paths": paths_dict, "name": task_name} + py_io.write_json( + data=config, path=os.path.join(output_base_path, "configs", f"{task_name}.json") + ) + + +@zconf.run_config +class RunConfiguration(zconf.RunConfig): + input_base_path = zconf.attr(type=str) + output_base_path = zconf.attr(type=str) + task_name_ls = zconf.attr(type=str, default=None) + + def _post_init(self): + if isinstance(self.task_name_ls, str): + self.task_name_ls = self.task_name_ls.split(",") + + +def main(): + args = RunConfiguration.default_run_cli() + preprocess_all_glue_data( + input_base_path=args.input_base_path, + output_base_path=args.output_base_path, + task_name_ls=args.task_name_ls, + ) + + +if __name__ == "__main__": + main() diff --git a/jiant/shared/__init__.py b/jiant/shared/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/jiant/shared/caching.py b/jiant/shared/caching.py new file mode 100644 index 000000000..a138acc68 --- /dev/null +++ b/jiant/shared/caching.py @@ -0,0 +1,277 @@ +import math +import numpy as np +import os +from typing import Generator, Union, Sequence + +import torch +import torch.utils.data.dataset + + +class Chunker: + def __init__(self, length, num_chunks, chunk_size): + self.length = length + self.num_chunks = num_chunks + self.chunk_size = chunk_size + + def get_slices(self): + indices = list(range(0, self.length, self.chunk_size)) + [self.length] + return [slice(start, end) for start, end in zip(indices[:-1], indices[1:])] + + def get_chunks(self, data): + assert len(data) == self.length + chunked_data = [data[data_slice] for data_slice in self.get_slices()] + assert len(chunked_data) == self.num_chunks + return chunked_data + + def lookup_chunk_and_index(self, i): + if isinstance(i, int): + return i // self.chunk_size, i % self.chunk_size + elif isinstance(i, np.ndarray): + i = i.astype(int) + return (i / self.chunk_size).astype(int), (i % self.chunk_size).astype(int) + elif isinstance(i, torch.Tensor): + return self.lookup_chunk_and_index(i.numpy()) + else: + raise TypeError(type(i)) + + def lookup_index(self, chunk_i, i): + if isinstance(i, (int, np.ndarray, torch.Tensor)): + return chunk_i * self.chunk_size + i + else: + raise TypeError(type(i)) + + @classmethod + def from_chunk_size(cls, length, chunk_size): + num_chunks = math.ceil(length / chunk_size) + return cls(length=length, num_chunks=num_chunks, chunk_size=chunk_size) + + +def convert_to_chunks(data, chunk_size: int): + """Divide data into chunks. + + Args: + data (List): data to divide into chunks. + chunk_size (int): number of data elements to store per chunk. + + Returns: + List of data chunks. + """ + chunker = Chunker.from_chunk_size(len(data), chunk_size=chunk_size) + chunked_data = chunker.get_chunks(data) + return chunked_data + + +def chunk_and_save(data: list, chunk_size: int, data_args: dict, output_dir: str): + """Divide data into chunks and save it to disk, also saves metadata describing chunking to disk. + + Args: + data (List): List of DataRows and metadata. + chunk_size (int): number of data elements to store per chunk. + data_args (Dict): RunConfiguration represented as a dictionary. + output_dir: phase-specific dir in the output dir specified in the RunConfiguration. + + """ + os.makedirs(output_dir, exist_ok=True) + chunked_data = convert_to_chunks(data=data, chunk_size=chunk_size) + for i, chunk in enumerate(chunked_data): + torch.save(chunk, os.path.join(output_dir, f"data_{i:05d}.chunk")) + data_args = data_args.copy() + data_args["num_chunks"] = len(chunked_data) + data_args["length"] = len(data) + torch.save(data_args, os.path.join(output_dir, "data_args.p")) + + +def iter_chunk_and_save( + data: Generator, chunk_size: int, data_args: dict, output_dir: str, recorder_callback=None +): + os.makedirs(output_dir, exist_ok=True) + chunk_i = 0 + length = 0 + current_chunk = [] + for datum in data: + if recorder_callback is not None: + recorder_callback(datum) + length += 1 + current_chunk.append(datum) + if len(current_chunk) == chunk_size: + torch.save(current_chunk, os.path.join(output_dir, f"data_{chunk_i:05d}.chunk")) + chunk_i += 1 + current_chunk = [] + if current_chunk: + torch.save(current_chunk, os.path.join(output_dir, f"data_{chunk_i:05d}.chunk")) + chunk_i += 1 + data_args = data_args.copy() + data_args["num_chunks"] = chunk_i + data_args["length"] = length + torch.save(data_args, os.path.join(output_dir, "data_args.p")) + + +def compare_tensor_tuples(tup1, tup2): + if len(tup1) != len(tup2): + return False + for col1, col2 in zip(tup1, tup2): + if not torch.equal(col1, col2): + return False + return True + + +def compare_dataset_with_metadata(d1, d2): + if not compare_tensor_tuples(d1.dataset.tensors, d2.dataset.tensors): + return False + if not d1.metadata == d2.metadata: + return False + return True + + +class DataCache: + # We're going to liberally use pickling/torch.save/load. + # There is no expectation that caches should be backward compatible. + + def get_all(self): + raise NotImplementedError() + + def iter_all(self): + raise NotImplementedError() + + def __len__(self): + raise NotImplementedError() + + +class InMemoryDataCache(DataCache): + def __init__(self, data): + self.data = data + + def get_all(self): + return self.data + + def iter_all(self): + for elem in self.data: + yield elem + + def __len__(self): + return len(self.data) + + +class ChunkedFilesDataCache(DataCache): + def __init__(self, cache_fol_path): + self.cache_fol_path = cache_fol_path + + self.data_args = torch.load(os.path.join(cache_fol_path, "data_args.p")) + self.num_chunks = self.data_args["num_chunks"] + self.length = self.data_args["length"] + self.chunk_size = self.data_args["chunk_size"] + self.chunker = Chunker.from_chunk_size(length=self.length, chunk_size=self.chunk_size) + + def get_iterable_dataset( + self, + buffer_size=None, + shuffle=False, + subset_num: Union[None, int] = None, + explicit_subset: Union[None, Sequence] = None, + verbose=False, + ): + return ChunkedFilesIterableDataset( + buffer_size=buffer_size, + shuffle=shuffle, + subset_num=subset_num, + explicit_subset=explicit_subset, + chunked_file_data_cache=self, + verbose=verbose, + ) + + def load_chunk(self, i): + return torch.load(self.get_chunk_path(i)) + + def get_chunk_path(self, i): + return os.path.join(self.cache_fol_path, f"data_{i:05d}.chunk") + + def load_from_indices(self, indices, verbose=False): + chunk_arr, chunk_sub_index_arr = self.chunker.lookup_chunk_and_index(indices) + reverse_index = np.arange(len(indices)).astype(int) + result = [None] * len(indices) + for chunk_i in sorted(list(set(chunk_arr))): + selector = chunk_arr == chunk_i + chunk = self.load_chunk(chunk_i) + selected_chunk_sub_index_arr = chunk_sub_index_arr[selector] + selected_reverse_index = reverse_index[selector] + if verbose: + print(f"Loading {len(selected_chunk_sub_index_arr)} indices from chunk {chunk_i}") + for i, j in zip(selected_chunk_sub_index_arr, selected_reverse_index): + result[j] = chunk[i] + del chunk + return result + + def get_all(self): + data = [] + for i in range(self.num_chunks): + data += list(self.load_chunk(i)) + return data + + def iter_all(self): + for i in range(self.num_chunks): + chunk = self.load_chunk(i) + for elem in chunk: + yield elem + + def __len__(self): + return self.length + + +class ChunkedFilesIterableDataset(torch.utils.data.dataset.IterableDataset): + def __init__( + self, + buffer_size, + shuffle, + chunked_file_data_cache: ChunkedFilesDataCache, + subset_num: Union[int, None] = None, + explicit_subset: Union[Sequence, None] = None, + verbose=False, + ): + self.buffer_size = buffer_size + self.shuffle = shuffle + self.subset_num = subset_num + self.chunked_file_data_cache = chunked_file_data_cache + self.explicit_subset = explicit_subset + self.verbose = verbose + + if self.explicit_subset is not None: + assert self.subset_num is None + self.length = len(self.explicit_subset) + else: + self.length = self.chunked_file_data_cache.length + if self.subset_num: + self.length = min(self.subset_num, self.length) + + if self.buffer_size is None: + self.buffer_size = self.length + + def __iter__(self): + seen = 0 + buffer_chunked_indices = self.get_buffer_chunked_indices() + for buffer_chunked_index in buffer_chunked_indices: + if self.verbose: + print( + f"Loading buffer {seen} - {seen + len(buffer_chunked_index)}" + f" out of {len(self)}" + ) + buffer = self.chunked_file_data_cache.load_from_indices( + buffer_chunked_index, verbose=self.verbose + ) + for elem in buffer: + yield elem + seen += len(buffer_chunked_index) + + def get_buffer_chunked_indices(self): + if self.explicit_subset is not None: + indices = np.array(self.explicit_subset).astype(int) + else: + indices = np.arange(self.length).astype(int) + if self.shuffle: + np.random.shuffle(indices) + if self.subset_num: + indices = indices[: self.subset_num] + buffer_chunked_indices = convert_to_chunks(indices, chunk_size=self.buffer_size) + return buffer_chunked_indices + + def __len__(self): + return self.length diff --git a/jiant/shared/constants.py b/jiant/shared/constants.py new file mode 100644 index 000000000..717316fd5 --- /dev/null +++ b/jiant/shared/constants.py @@ -0,0 +1,4 @@ +class PHASE: + TRAIN = "train" + VAL = "val" + TEST = "test" diff --git a/jiant/shared/distributed.py b/jiant/shared/distributed.py new file mode 100644 index 000000000..823a9e5c7 --- /dev/null +++ b/jiant/shared/distributed.py @@ -0,0 +1,16 @@ +from contextlib import contextmanager +import torch + + +@contextmanager +def only_first_process(local_rank): + if local_rank not in [-1, 0]: + # noinspection PyUnresolvedReferences + torch.distributed.barrier() + + try: + yield + finally: + if local_rank == 0: + # noinspection PyUnresolvedReferences + torch.distributed.barrier() diff --git a/jiant/shared/initialization.py b/jiant/shared/initialization.py new file mode 100644 index 000000000..390b8011b --- /dev/null +++ b/jiant/shared/initialization.py @@ -0,0 +1,200 @@ +import json +import numpy as np +import os +import random +import time +import torch +from dataclasses import dataclass +from typing import Any + +import jiant.utils.python.io as py_io +import jiant.utils.zlog as zlog + + +@dataclass +class QuickInitContainer: + device: Any + n_gpu: int + log_writer: Any + + +def quick_init(args, verbose=True) -> QuickInitContainer: + """Sets up logging, initializes device(s) and random seed, prepares output dir, and saves args." + + Args: + args (RunConfiguration): configuration carrying command line args specifying run params. + verbose (bool): whether to print the input run config and the run config as saved. + + Returns: + QuickInitContainer specifying the run's device, GPU count, and logging configuration. + + """ + if verbose: + print_args(args) + init_server_logging(server_ip=args.server_ip, server_port=args.server_port, verbose=verbose) + device, n_gpu = init_cuda_from_args( + no_cuda=args.no_cuda, local_rank=args.local_rank, fp16=args.fp16, verbose=verbose, + ) + args.seed = init_seed(given_seed=args.seed, n_gpu=n_gpu, verbose=verbose) + init_output_dir(output_dir=args.output_dir, force_overwrite=args.force_overwrite) + log_writer = init_log_writer(output_dir=args.output_dir) + save_args(args=args, verbose=verbose) + return QuickInitContainer(device=device, n_gpu=n_gpu, log_writer=log_writer) + + +def init_server_logging(server_ip, server_port, verbose=True): + """Sets ups Python Tools for Visual Studio debug (ptvsd) server. + + Adapted from Hugging Face template: https://github.com/huggingface/transformers/blob/ac99217 + e92c43066af7ec96554054d75532565d7/templates/adding_a_new_example_script/run_xxx.py#L569-L576 + + """ + if server_ip and server_port: + # Distant debugging, see: + # https://code.visualstudio.com/docs/python/debugging#_attach-to-a-local-script + # noinspection PyUnresolvedReferences,PyPackageRequirements + import ptvsd + + if verbose: + print("Waiting for debugger attach") + ptvsd.enable_attach(address=(server_ip, server_port), redirect_output=True) + ptvsd.wait_for_attach() + + +def init_cuda_from_args(no_cuda, local_rank, fp16, verbose=True): + """Perform initial CUDA setup for DistributedDataParallel, DataParallel or w/o CUDA configs. + + Adapted from Hugging Face template: https://github.com/huggingface/transformers/blob/ac99217e92 + c43066af7ec96554054d75532565d7/templates/adding_a_new_example_script/run_xxx.py#L578-L586 + + Args: + no_cuda (bool): True to ignore CUDA devices (i.e., use CPU instead). + local_rank (int): Which GPU the script should use in DistributedDataParallel mode. + fp16 (bool): True for half-precision mode. + verbose: True to print device, device count, and whether training is distributed or FP16. + + Notes: + local_rank == -1 is used to indicate that DistributedDataParallel should be disabled. + n_gpu > 1 is used to indicate that DataParallel should be used. Currently, local_rank == -1 + sets n_gpu = 1 even if torch.cuda.device_count() would show more than one GPU is available. + + Returns: + (tuple): tuple containing: + device (str): string handle for device. + n_gpu (int): number of GPU devices. + + """ + # TODO break local_rank == -1 and no_cuda into separate cases to make the logic easier to read. + if local_rank == -1 or no_cuda: + device = torch.device("cuda" if torch.cuda.is_available() and not no_cuda else "cpu") + n_gpu = torch.cuda.device_count() + else: + torch.cuda.set_device(local_rank) + device = torch.device("cuda", local_rank) + n_gpu = 1 + # Initializes the distributed backend which will take care of synchronizing nodes/GPUs + # noinspection PyUnresolvedReferences + torch.distributed.init_process_group(backend="nccl") + if verbose: + print( + "device: {} n_gpu: {}, distributed training: {}, 16-bits training: {}".format( + device, n_gpu, bool(local_rank != -1), fp16 + ) + ) + + return device, n_gpu + + +def init_seed(given_seed, n_gpu, verbose=True): + """Initializes random seeds for sources of randomness. If seed is -1, randomly select seed. + + Sets the random seed for sources of randomness (numpy, torch and python random). If seed is + specified as -1, the seed will be randomly selected and used to initialize all random seeds. + The value used to initialize the random seeds is returned. + + Args: + given_seed (int): random seed. + n_gpu (int): number of GPUs. + verbose: whether to print random seed. + + Returns: + int: value used to initialize random seeds. + + """ + used_seed = get_seed(given_seed) + random.seed(used_seed) + np.random.seed(used_seed) + torch.manual_seed(used_seed) + if verbose: + print("Using seed: {}".format(used_seed)) + + if n_gpu > 0: + # noinspection PyUnresolvedReferences + torch.cuda.manual_seed_all(used_seed) + + # MAKE SURE THIS IS SET + return used_seed + + +def init_output_dir(output_dir, force_overwrite): + """Create output directory (and all intermediate dirs on the path) if it doesn't exist. + + Args: + output_dir (str): output directory path. + force_overwrite (bool): If False and output dir is complete, raise RuntimeError. + + Raises: + RuntimeError if overwrite option is not enabled and output dir contains "DONE" signal file. + + """ + if not force_overwrite and is_done(output_dir): + raise RuntimeError(f"'{output_dir}' run is already done, and not forcing overwrite") + os.makedirs(output_dir, exist_ok=True) + + +def init_log_writer(output_dir): + return zlog.ZLogger(os.path.join(output_dir, str(int(time.time()))), overwrite=True) + + +def print_args(args): + for k, v in vars(args).items(): + print(" {}: {}".format(k, v)) + + +def save_args(args, verbose=True): + """Dumps RunConfiguration to a json file. + + Args: + args (RunConfiguration): configuration carrying command line args specifying run params. + verbose (bool): If True, print the arg object that was written to file. + + """ + formatted_args = json.dumps(vars(args), indent=2) + with open(os.path.join(args.output_dir, "args.json"), "w") as f: + f.write(formatted_args) + if verbose: + print(formatted_args) + + +def get_seed(seed): + """Get random seed if seed is specified as -1, otherwise return seed. + + Args: + seed (int): random seed. + + Returns: + int: Random seed if seed is specified as -1, otherwise returns the provided input seed. + + """ + if seed == -1: + return int(np.random.randint(0, 2 ** 32 - 1)) + else: + return seed + + +def write_done(output_dir): + py_io.write_file("DONE", os.path.join(output_dir, "DONE")) + + +def is_done(output_dir): + return os.path.exists(os.path.join(output_dir, "DONE")) diff --git a/jiant/shared/metarunner.py b/jiant/shared/metarunner.py new file mode 100644 index 000000000..0d0c6ca43 --- /dev/null +++ b/jiant/shared/metarunner.py @@ -0,0 +1,54 @@ +class AbstractMetarunner: + def begin_training(self): + raise NotImplementedError() + + def yield_train_step(self): + raise NotImplementedError() + + def should_save_model(self) -> bool: + raise NotImplementedError() + + def save_model(self): + raise NotImplementedError() + + def should_save_checkpoint(self) -> bool: + raise NotImplementedError() + + def save_checkpoint(self): + raise NotImplementedError() + + def should_eval_model(self) -> bool: + raise NotImplementedError() + + def eval_model(self): + raise NotImplementedError() + + def should_break_training(self) -> bool: + raise NotImplementedError() + + def done_training(self): + raise NotImplementedError() + + def returned_result(self): + raise NotImplementedError() + + def run_train_loop(self): + self.begin_training() + + for _ in self.yield_train_step(): + if self.should_save_model(): + self.save_model() + + if self.should_save_checkpoint(): + self.save_checkpoint() + + if self.should_eval_model(): + self.eval_model() + + if self.should_break_training(): + break + + self.eval_model() + self.done_training() + + return self.returned_result() diff --git a/jiant/shared/model_resolution.py b/jiant/shared/model_resolution.py new file mode 100644 index 000000000..aeba39a9b --- /dev/null +++ b/jiant/shared/model_resolution.py @@ -0,0 +1,320 @@ +from dataclasses import dataclass +from enum import Enum + +import transformers + +from jiant.tasks.core import FeaturizationSpec + + +class ModelArchitectures(Enum): + BERT = 1 + XLM = 2 + ROBERTA = 3 + ALBERT = 4 + XLM_ROBERTA = 5 + BART = 6 + MBART = 7 + ELECTRA = 8 + + @classmethod + def from_model_type(cls, model_type: str): + """Get the model architecture for the provided shortcut name. + + Args: + model_type (str): model shortcut name. + + Returns: + Model architecture associated with the provided shortcut name. + + """ + if model_type.startswith("bert-"): + return cls.BERT + elif model_type.startswith("xlm-") and not model_type.startswith("xlm-roberta"): + return cls.XLM + elif model_type.startswith("roberta-"): + return cls.ROBERTA + elif model_type.startswith("albert-"): + return cls.ALBERT + elif model_type == "glove_lstm": + return cls.GLOVE_LSTM + elif model_type.startswith("xlm-roberta-"): + return cls.XLM_ROBERTA + elif model_type.startswith("bart-"): + return cls.BART + elif model_type.startswith("mbart-"): + return cls.MBART + elif model_type.startswith("electra-"): + return cls.ELECTRA + else: + raise KeyError(model_type) + + @classmethod + def from_transformers_model(cls, transformers_model): + if isinstance( + transformers_model, transformers.BertPreTrainedModel + ) and transformers_model.__class__.__name__.startswith("Bert"): + return cls.BERT + elif isinstance(transformers_model, transformers.XLMPreTrainedModel): + return cls.XLM + elif isinstance( + transformers_model, transformers.BertPreTrainedModel + ) and transformers_model.__class__.__name__.startswith("Robert"): + return cls.ROBERTA + elif isinstance( + transformers_model, transformers.BertPreTrainedModel + ) and transformers_model.__class__.__name__.startswith("XLMRoberta"): + return cls.XLM_ROBERTA + elif isinstance(transformers_model, transformers.modeling_albert.AlbertPreTrainedModel): + return cls.ALBERT + elif isinstance(transformers_model, transformers.modeling_bart.PretrainedBartModel): + return bart_or_mbart_model_heuristic(model_config=transformers_model.config) + elif isinstance(transformers_model, transformers.modeling_electra.ElectraPreTrainedModel): + return cls.ELECTRA + else: + raise KeyError(str(transformers_model)) + + @classmethod + def from_tokenizer_class(cls, tokenizer_class): + if isinstance(tokenizer_class, transformers.BertTokenizer): + return cls.BERT + elif isinstance(tokenizer_class, transformers.XLMTokenizer): + return cls.XLM + elif isinstance(tokenizer_class, transformers.RobertaTokenizer): + return cls.ROBERTA + elif isinstance(tokenizer_class, transformers.XLMRobertaTokenizer): + return cls.XLM_ROBERTA + elif isinstance(tokenizer_class, transformers.AlbertTokenizer): + return cls.ALBERT + elif isinstance(tokenizer_class, transformers.BartTokenizer): + return cls.BART + elif isinstance(tokenizer_class, transformers.MBartTokenizer): + return cls.MBART + elif isinstance(tokenizer_class, transformers.ElectraTokenizer): + return cls.ELECTRA + else: + raise KeyError(str(tokenizer_class)) + + @classmethod + def is_transformers_model_arch(cls, model_arch): + return model_arch in [ + cls.BERT, + cls.XLM, + cls.ROBERTA, + cls.ALBERT, + cls.XLM_ROBERTA, + cls.BART, + cls.MBART, + cls.ELECTRA, + ] + + @classmethod + def from_encoder(cls, encoder): + if ( + isinstance(encoder, transformers.BertModel) + and encoder.__class__.__name__ == "BertModel" + ): + return cls.BERT + elif ( + isinstance(encoder, transformers.XLMModel) and encoder.__class__.__name__ == "XLMModel" + ): + return cls.XLM + elif ( + isinstance(encoder, transformers.RobertaModel) + and encoder.__class__.__name__ == "RobertaModel" + ): + return cls.ROBERTA + elif ( + isinstance(encoder, transformers.AlbertModel) + and encoder.__class__.__name__ == "AlbertModel" + ): + return cls.ALBERT + elif ( + isinstance(encoder, transformers.XLMRobertaModel) + and encoder.__class__.__name__ == "XlmRobertaModel" + ): + return cls.XLM_ROBERTA + elif ( + isinstance(encoder, transformers.BartModel) + and encoder.__class__.__name__ == "BartModel" + ): + return bart_or_mbart_model_heuristic(model_config=encoder.config) + elif ( + isinstance(encoder, transformers.ElectraModel) + and encoder.__class__.__name__ == "ElectraModel" + ): + return cls.ELECTRA + else: + raise KeyError(type(encoder)) + + +@dataclass +class ModelClassSpec: + config_class: type + tokenizer_class: type + model_class: type + + +def build_featurization_spec(model_type, max_seq_length): + model_arch = ModelArchitectures.from_model_type(model_type) + if model_arch == ModelArchitectures.BERT: + return FeaturizationSpec( + max_seq_length=max_seq_length, + cls_token_at_end=False, + pad_on_left=False, + cls_token_segment_id=0, + pad_token_segment_id=0, + pad_token_id=0, + pad_token_mask_id=0, + sequence_a_segment_id=0, + sequence_b_segment_id=1, + sep_token_extra=False, + ) + elif model_arch == ModelArchitectures.XLM: + return FeaturizationSpec( + max_seq_length=max_seq_length, + cls_token_at_end=False, + pad_on_left=False, + cls_token_segment_id=0, + pad_token_segment_id=0, + pad_token_id=0, + pad_token_mask_id=0, + sequence_a_segment_id=0, + sequence_b_segment_id=0, # RoBERTa has no token_type_ids + sep_token_extra=False, + ) + elif model_arch == ModelArchitectures.ROBERTA: + # RoBERTa is weird + # token 0 = '' which is the cls_token + # token 1 = '' which is the sep_token + # Also two ''s are used between sentences. Yes, not ''. + return FeaturizationSpec( + max_seq_length=max_seq_length, + cls_token_at_end=False, + pad_on_left=False, + cls_token_segment_id=0, + pad_token_segment_id=0, + pad_token_id=1, # Roberta uses pad_token_id = 1 + pad_token_mask_id=0, + sequence_a_segment_id=0, + sequence_b_segment_id=0, # RoBERTa has no token_type_ids + sep_token_extra=True, + ) + elif model_arch == ModelArchitectures.ALBERT: + # + return FeaturizationSpec( + max_seq_length=max_seq_length, + cls_token_at_end=False, # ? + pad_on_left=False, # ok + cls_token_segment_id=0, # ok + pad_token_segment_id=0, # ok + pad_token_id=0, # I think? + pad_token_mask_id=0, # I think? + sequence_a_segment_id=0, # I think? + sequence_b_segment_id=1, # I think? + sep_token_extra=False, + ) + elif model_arch == ModelArchitectures.XLM_ROBERTA: + # XLM-RoBERTa is weird + # token 0 = '' which is the cls_token + # token 1 = '' which is the sep_token + # Also two ''s are used between sentences. Yes, not ''. + return FeaturizationSpec( + max_seq_length=max_seq_length, + cls_token_at_end=False, + pad_on_left=False, + cls_token_segment_id=0, + pad_token_segment_id=0, + pad_token_id=1, # XLM-RoBERTa uses pad_token_id = 1 + pad_token_mask_id=0, + sequence_a_segment_id=0, + sequence_b_segment_id=0, # XLM-RoBERTa has no token_type_ids + sep_token_extra=True, + ) + elif model_arch == ModelArchitectures.BART: + # BART is weird + # token 0 = '' which is the cls_token + # token 1 = '' which is the sep_token + # Also two ''s are used between sentences. Yes, not ''. + return FeaturizationSpec( + max_seq_length=max_seq_length, + cls_token_at_end=False, + pad_on_left=False, + cls_token_segment_id=0, + pad_token_segment_id=0, + pad_token_id=1, # BART uses pad_token_id = 1 + pad_token_mask_id=0, + sequence_a_segment_id=0, + sequence_b_segment_id=0, # BART has no token_type_ids + sep_token_extra=True, + ) + elif model_arch == ModelArchitectures.MBART: + # mBART is weird + # token 0 = '' which is the cls_token + # token 1 = '' which is the sep_token + # Also two ''s are used between sentences. Yes, not ''. + return FeaturizationSpec( + max_seq_length=max_seq_length, + cls_token_at_end=False, + pad_on_left=False, + cls_token_segment_id=0, + pad_token_segment_id=0, + pad_token_id=1, # mBART uses pad_token_id = 1 + pad_token_mask_id=0, + sequence_a_segment_id=0, + sequence_b_segment_id=0, # mBART has no token_type_ids + sep_token_extra=True, + ) + elif model_arch == ModelArchitectures.ELECTRA: + return FeaturizationSpec( + max_seq_length=max_seq_length, + cls_token_at_end=False, + pad_on_left=False, + cls_token_segment_id=0, + pad_token_segment_id=0, + pad_token_id=0, + pad_token_mask_id=0, + sequence_a_segment_id=0, + sequence_b_segment_id=1, + sep_token_extra=False, + ) + else: + raise KeyError(model_arch) + + +TOKENIZER_CLASS_DICT = { + ModelArchitectures.BERT: transformers.BertTokenizer, + ModelArchitectures.XLM: transformers.XLMTokenizer, + ModelArchitectures.ROBERTA: transformers.RobertaTokenizer, + ModelArchitectures.XLM_ROBERTA: transformers.XLMRobertaTokenizer, + ModelArchitectures.ALBERT: transformers.AlbertTokenizer, + ModelArchitectures.BART: transformers.BartTokenizer, + ModelArchitectures.MBART: transformers.MBartTokenizer, + ModelArchitectures.ELECTRA: transformers.ElectraTokenizer, +} + + +def resolve_tokenizer_class(model_type): + """Get tokenizer class for a given model architecture. + + Args: + model_type (str): model shortcut name. + + Returns: + Tokenizer associated with the given model. + + """ + return TOKENIZER_CLASS_DICT[ModelArchitectures.from_model_type(model_type)] + + +def resolve_is_lower_case(tokenizer): + if isinstance(tokenizer, (transformers.BertTokenizer, transformers.AlbertTokenizer)): + return tokenizer.basic_tokenizer.do_lower_case + else: + return False + + +def bart_or_mbart_model_heuristic(model_config: transformers.BartConfig) -> ModelArchitectures: + if model_config.is_valid_mbart(): + return ModelArchitectures.MBART + else: + return ModelArchitectures.BART diff --git a/jiant/shared/model_setup.py b/jiant/shared/model_setup.py new file mode 100644 index 000000000..427e399c5 --- /dev/null +++ b/jiant/shared/model_setup.py @@ -0,0 +1,229 @@ +import transformers +import torch + +from jiant.ext.radam import RAdam +from jiant.shared.model_resolution import ModelArchitectures, resolve_tokenizer_class + + +def get_tokenizer(model_type, tokenizer_path): + """Instantiate a tokenizer for a given model type. + + Args: + model_type (str): model shortcut name. + tokenizer_path (str): path to tokenizer directory. + + Returns: + Tokenizer for the given model type. + + """ + model_arch = ModelArchitectures.from_model_type(model_type) + tokenizer_class = resolve_tokenizer_class(model_type) + if model_arch in [ModelArchitectures.BERT]: + if "-cased" in model_type: + do_lower_case = False + elif "-uncased" in model_type: + do_lower_case = True + else: + raise RuntimeError(model_type) + elif model_arch in [ + ModelArchitectures.XLM, + ModelArchitectures.ROBERTA, + ModelArchitectures.XLM_ROBERTA, + ModelArchitectures.BART, + ModelArchitectures.MBART, + ModelArchitectures.ELECTRA, + ]: + do_lower_case = False + elif model_arch in [ModelArchitectures.ALBERT]: + do_lower_case = True + else: + raise RuntimeError(str(tokenizer_class)) + tokenizer = tokenizer_class.from_pretrained(tokenizer_path, do_lower_case=do_lower_case) + return tokenizer + + +class OptimizerScheduler: + def __init__(self, optimizer, scheduler): + super().__init__() + self.optimizer = optimizer + self.scheduler = scheduler + + def step(self): + self.optimizer.step() + self.scheduler.step() + + def state_dict(self): + return { + "optimizer": self.optimizer.state_dict(), + "scheduler": self.scheduler.state_dict(), + } + + def load_state_dict(self, state_dict, strict=True): + self.optimizer.load_state_dict(state_dict["optimizer"], strict=strict) + self.scheduler.load_state_dict(state_dict["scheduler"], strict=strict) + + +def create_optimizer( + model, + learning_rate, + t_total, + warmup_steps, + warmup_proportion, + optimizer_epsilon=1e-8, + optimizer_type="adam", + verbose=False, +): + return create_optimizer_from_params( + named_parameters=list(model.named_parameters()), + learning_rate=learning_rate, + t_total=t_total, + warmup_steps=warmup_steps, + warmup_proportion=warmup_proportion, + optimizer_epsilon=optimizer_epsilon, + optimizer_type=optimizer_type, + verbose=verbose, + ) + + +def create_optimizer_from_params( + named_parameters, + learning_rate, + t_total, + warmup_steps, + warmup_proportion, + optimizer_epsilon=1e-8, + optimizer_type="adam", + verbose=False, +): + # Prepare optimizer + no_decay = [ + "bias", + "LayerNorm.bias", + "LayerNorm.weight", + "adapter.down_project.weight", + "adapter.up_project.weight", + "weighted_sum.weights", + ] + if verbose: + print("No optimizer decay for:") + for n, p in named_parameters: + if any(nd in n for nd in no_decay): + print(f" {n}") + + used_named_parameters = [ + (n, p) for n, p in named_parameters if p.requires_grad and "weighted_sum.weights" not in n + ] + weighted_sum_params = [ + (n, p) for n, p in named_parameters if p.requires_grad and "weighted_sum.weights" in n + ] + + optimizer_grouped_parameters = [ + { + "params": [p for n, p in used_named_parameters if not any(nd in n for nd in no_decay)], + "weight_decay": 0.01, + }, + { + "params": [p for n, p in used_named_parameters if any(nd in n for nd in no_decay)], + "weight_decay": 0.0, + }, + {"params": [p for n, p in weighted_sum_params], "weight_decay": 0.0, "lr": 0.01}, + ] + + if optimizer_type == "adam": + if verbose: + print("Using AdamW") + optimizer = transformers.AdamW( + optimizer_grouped_parameters, lr=learning_rate, eps=optimizer_epsilon + ) + elif optimizer_type == "radam": + if verbose: + print("Using RAdam") + optimizer = RAdam(optimizer_grouped_parameters, lr=learning_rate, eps=optimizer_epsilon) + else: + raise KeyError(optimizer_type) + + warmup_steps = resolve_warmup_steps( + t_total=t_total, warmup_steps=warmup_steps, warmup_proportion=warmup_proportion, + ) + scheduler = transformers.get_linear_schedule_with_warmup( + optimizer, num_warmup_steps=warmup_steps, num_training_steps=t_total + ) + optimizer_scheduler = OptimizerScheduler(optimizer=optimizer, scheduler=scheduler) + return optimizer_scheduler + + +def resolve_warmup_steps(t_total, warmup_steps, warmup_proportion): + if warmup_steps is None and warmup_proportion is None: + raise RuntimeError() + elif warmup_steps is not None and warmup_proportion is not None: + raise RuntimeError() + elif warmup_steps is None and warmup_proportion is not None: + return warmup_proportion * t_total + elif warmup_steps is not None and warmup_proportion is None: + return warmup_steps + else: + raise RuntimeError() + + +def fp16ize(model, optimizer, fp16_opt_level): + try: + # noinspection PyUnresolvedReferences,PyPackageRequirements + from apex import amp + except ImportError: + raise ImportError( + "Please install apex from https://www.github.com/nvidia/apex to use fp16 training." + ) + model, optimizer = amp.initialize(model, optimizer, opt_level=fp16_opt_level) + return model, optimizer + + +def parallelize_gpu(model): + return torch.nn.DataParallel(model) + + +def parallelize_dist(model, local_rank): + return torch.nn.parallel.DistributedDataParallel( + model, device_ids=[local_rank], output_device=local_rank, + ) + + +def raw_special_model_setup(model, optimizer, fp16, fp16_opt_level, n_gpu, local_rank): + """Perform setup for special modes (e.g., FP16, DataParallel, and/or DistributedDataParallel. + + Args: + model (nn.Module): torch model object. + optimizer: TODO + fp16 (bool): True to enable FP16 mode. + fp16_opt_level (str): Apex AMP optimization level default mode identifier. + n_gpu: number of GPUs. + local_rank (int): Which GPU the script should use in DistributedDataParallel mode. + + Notes: + Initialization steps performed in init_cuda_from_args() set n_gpu = 1 when local_rank != -1. + + Returns: + Model and optimizer with the specified special configuration. + + """ + if fp16: + model, optimizer = fp16ize(model=model, optimizer=optimizer, fp16_opt_level=fp16_opt_level) + if n_gpu > 1: + model = parallelize_gpu(model=model) + if local_rank != -1: + model = parallelize_dist(model=model, local_rank=local_rank) + return model, optimizer + + +def special_model_setup( + model_wrapper, optimizer_scheduler, fp16, fp16_opt_level, n_gpu, local_rank +): + model, optimizer = raw_special_model_setup( + model=model_wrapper.model, + optimizer=optimizer_scheduler.optimizer, + fp16=fp16, + fp16_opt_level=fp16_opt_level, + n_gpu=n_gpu, + local_rank=local_rank, + ) + model_wrapper.model = model + optimizer_scheduler.optimizer = optimizer diff --git a/jiant/shared/runner.py b/jiant/shared/runner.py new file mode 100644 index 000000000..f1c67c6b3 --- /dev/null +++ b/jiant/shared/runner.py @@ -0,0 +1,67 @@ +import os + +import torch +import torch.nn as nn + +import jiant.shared.caching as caching +import jiant.utils.python.io as py_io +import jiant.utils.torch_utils as torch_utils + + +def complex_backpropagate( + loss, optimizer, model, fp16, n_gpu, gradient_accumulation_steps, max_grad_norm +): + if n_gpu > 1: + loss = loss.mean() # mean() to average on multi-gpu. + if gradient_accumulation_steps > 1: + loss = loss / gradient_accumulation_steps + if fp16: + # noinspection PyUnresolvedReferences,PyPackageRequirements + from apex import amp + + with amp.scale_loss(loss, optimizer) as scaled_loss: + scaled_loss.backward() + torch.nn.utils.clip_grad_norm_(amp.master_params(optimizer), max_grad_norm) + else: + loss.backward() + torch.nn.utils.clip_grad_norm_(model.parameters(), max_grad_norm) + return loss + + +def get_train_dataloader_from_cache( + train_cache: caching.ChunkedFilesDataCache, task, train_batch_size: int +): + # TODO: Expose buffer_size parameter (Issue #50) + dataset = train_cache.get_iterable_dataset(buffer_size=10000, shuffle=True) + train_dataloader = torch_utils.DataLoaderWithLength( + dataset=dataset, batch_size=train_batch_size, collate_fn=task.collate_fn, + ) + return train_dataloader + + +def get_eval_dataloader_from_cache( + eval_cache: caching.ChunkedFilesDataCache, + task, + eval_batch_size: int, + subset_num=None, + explicit_subset=None, +): + dataset = eval_cache.get_iterable_dataset( + buffer_size=10000, shuffle=False, subset_num=subset_num, explicit_subset=explicit_subset, + ) + eval_dataloader = torch_utils.DataLoaderWithLength( + dataset=dataset, batch_size=eval_batch_size, collate_fn=task.collate_fn, + ) + return eval_dataloader + + +def save_model_with_metadata(model: nn.Module, metadata: dict, output_dir: str, file_name="model"): + torch.save( + torch_utils.get_model_for_saving(model).state_dict(), + os.path.join(output_dir, f"{file_name}.p"), + ) + py_io.write_json(metadata, os.path.join(output_dir, f"{file_name}.metadata.json")) + + +def compare_steps_max_steps(step, max_steps): + return max_steps is not None and max_steps != -1 and step >= max_steps diff --git a/jiant/tasks/__init__.py b/jiant/tasks/__init__.py index 808c540b6..28093f838 100644 --- a/jiant/tasks/__init__.py +++ b/jiant/tasks/__init__.py @@ -1,106 +1,2 @@ -# Import task definitions to register their tasks. -from jiant.tasks import ( - edge_probing, - lm, - nli_probing, - qa, - seq2seq, - tasks, - senteval_probing, - acceptablity_probing, -) - -# REGISTRY needs to be available to modules within this package, -# but we also import it here to make it available at the package level. -from jiant.tasks.registry import REGISTRY - -# Task class definition -from jiant.tasks.tasks import Task - -## -# Task lists for handling as a group; these names correspond to the keys in -# the task registry. -ALL_GLUE_TASKS = [ - "sst", - "cola", - "mrpc", - "qqp", - "sts-b", - "mnli", - "qnli", - "rte", - "wnli", - "glue-diagnostic", -] - -ALL_SUPERGLUE_TASKS = [ - "boolq", - "commitbank", - "copa", - "multirc", - "record", - "rte-superglue", - "winograd-coreference", - "wic", - "broadcoverage-diagnostic", - "winogender-diagnostic", -] - -ALL_DIAGNOSTICS = ["broadcoverage-diagnostic", "winogender-diagnostic", "glue-diagnostic"] -# Tasks for the spring19_seminar; similar to cola but write predictions differently -ALL_COLA_NPI_TASKS = [ - "cola-npi-sup", - "cola-npi-quessmp", - "cola-npi-ques", - "cola-npi-qnt", - "cola-npi-only", - "cola-npi-negsent", - "cola-npi-negdet", - "cola-npi-cond", - "cola-npi-adv", - "hd-cola-npi-sup", - "hd-cola-npi-quessmp", - "hd-cola-npi-ques", - "hd-cola-npi-qnt", - "hd-cola-npi-only", - "hd-cola-npi-negsent", - "hd-cola-npi-negdet", - "hd-cola-npi-cond", - "hd-cola-npi-adv", - "all-cola-npi", - "wilcox-npi", - "npi-adv-li", - "npi-adv-sc", - "npi-adv-pr", - "npi-cond-li", - "npi-cond-sc", - "npi-cond-pr", - "npi-negdet-li", - "npi-negdet-sc", - "npi-negdet-pr", - "npi-negsent-li", - "npi-negsent-sc", - "npi-negsent-pr", - "npi-only-li", - "npi-only-sc", - "npi-only-pr", - "npi-qnt-li", - "npi-qnt-sc", - "npi-qnt-pr", - "npi-ques-li", - "npi-ques-sc", - "npi-ques-pr", - "npi-quessmp-li", - "npi-quessmp-sc", - "npi-quessmp-pr", - "npi-sup-li", - "npi-sup-sc", - "npi-sup-pr", -] - -# Seq2seq tasks -ALL_SEQ2SEQ_TASKS = ["seg-wix"] - -# people are mostly using nli-prob for now, but we will change to -# using individual tasks later, so better to have as a list -ALL_NLI_PROBING_TASKS = ["nli-prob", "nps", "nli-prob-prepswap", "nli-prob-negation", "nli-alt"] +from .retrieval import * # noqa: F401,F403 +from .core import BatchMixin, TaskTypes # noqa: F401 diff --git a/jiant/tasks/acceptablity_probing.py b/jiant/tasks/acceptablity_probing.py deleted file mode 100644 index a784f5010..000000000 --- a/jiant/tasks/acceptablity_probing.py +++ /dev/null @@ -1,79 +0,0 @@ -"""Task definitions for acceptablity probing tasks.""" -import logging as log -import os - -from jiant.utils.data_loaders import load_tsv -from jiant.tasks.registry import register_task -from jiant.tasks.tasks import SingleClassificationTask -from allennlp.training.metrics import CategoricalAccuracy, F1Measure - - -@register_task("acceptability-def", "FunctionWordsProbing/definiteness/") -@register_task("acceptability-conj", "FunctionWordsProbing/coordinating-conjunctions/") -@register_task("acceptability-wh", "FunctionWordsProbing/whwords/") -@register_task("acceptability-eos", "FunctionWordsProbing/eos/") -class AcceptabilityProbingTask(SingleClassificationTask): - """ Task class for A-type Probing Task - This probing task only have evaluation set, need to share classifier with NLI-type task. - At present, 4 tasks are registered under this class, - acceptability-def tests model's understanding of definiteness - acceptability-conj tests that of coordinating conjunctions - acceptability-wh tests that of wh-words - acceptability-eos tests that of EOS - """ - - def __init__(self, path, max_seq_len, name, fold_no=1, **kw): - super(AcceptabilityProbingTask, self).__init__(name, n_classes=2, **kw) - self.path = path - self.max_seq_len = max_seq_len - self.scorer2 = F1Measure(1) - self.scorers = [self.scorer1, self.scorer2] - self.fold_no = fold_no - self.val_metric = "%s_acc_f1" % self.name - self.val_metric_decreases = False - - def load_data(self): - fold_no = self.fold_no - tr_data = load_tsv( - self._tokenizer_name, - os.path.join(self.path, "fold{}/train.tsv".format(fold_no)), - self.max_seq_len, - s1_idx=1, - s2_idx=None, - label_idx=2, - label_fn=lambda label_str: {"acceptable": 1, "unacceptable": 0}[label_str], - skip_rows=0, - ) - val_data = load_tsv( - self.tokenizer_name, - os.path.join(self.path, "fold{}/dev.tsv".format(fold_no)), - self.max_seq_len, - s1_idx=1, - s2_idx=None, - label_idx=2, - label_fn=lambda label_str: {"acceptable": 1, "unacceptable": 0}[label_str], - skip_rows=0, - ) - te_data = load_tsv( - self.tokenizer_name, - os.path.join(self.path, "fold{}/test.tsv".format(fold_no)), - self.max_seq_len, - s1_idx=1, - s2_idx=None, - label_idx=2, - label_fn=lambda label_str: {"acceptable": 1, "unacceptable": 0}[label_str], - skip_rows=0, - ) - - self.train_data_text = tr_data - self.val_data_text = val_data - self.test_data_text = te_data - self.sentences = self.train_data_text[0] + self.val_data_text[0] - log.info( - "\tFinished loading acceptability probing {} data (fold{}).".format(self.name, fold_no) - ) - - def get_metrics(self, reset=False): - acc = self.scorer1.get_metric(reset) - pcs, rcl, f1 = self.scorer2.get_metric(reset) - return {"acc_f1": (acc + f1) / 2, "accuracy": acc, "f1": f1} diff --git a/jiant/tasks/constants.py b/jiant/tasks/constants.py new file mode 100644 index 000000000..4c68dac9c --- /dev/null +++ b/jiant/tasks/constants.py @@ -0,0 +1,49 @@ +GLUE_TASKS = { + "cola", + "sst", + "mrpc", + "qqp", + "stsb", + "mnli", + "mnli_mismatched", + "qnli", + "rte", + "wnli", + "glue_diagnostics", +} + +SUPERGLUE_TASKS = { + "cb", + "copa", + "multirc", + "wic", + "wsc", + "boolq", + "record", + "rte", + "superglue_broadcoverage_diagnostics", + "superglue_winogender_diagnostics", +} + +OTHER_NLP_TASKS = { + "snli", + "commonsenseqa", + "hellaswag", + "cosmosqa", + "socialiqa", + "scitail", +} + +XTREME_TASKS = { + "xnli", + "pawsx", + "udpos", + "panx", + "xquad", + "mlqa", + "tydiqa", + "bucc2018", + "tatoeba", +} + +BENCHMARKS = {"GLUE": GLUE_TASKS, "SUPERGLUE": SUPERGLUE_TASKS, "XTREME": XTREME_TASKS} diff --git a/jiant/tasks/core.py b/jiant/tasks/core.py new file mode 100644 index 000000000..59471f163 --- /dev/null +++ b/jiant/tasks/core.py @@ -0,0 +1,226 @@ +import numpy as np +from typing import NamedTuple, Mapping, Dict +from enum import Enum +from dataclasses import dataclass + +import torch +import torch.utils.data.dataloader as dataloader + +from jiant.utils.python.datastructures import ExtendedDataClassMixin, combine_dicts + + +@dataclass +class FeaturizationSpec: + """Tokenization-related metadata. + + Attributes: + max_seq_length (int): The maximum total input sequence length after tokenization. + cls_token_at_end (bool): True if class token is located at end, False if at beginning. + pad_on_left (bool): True if padding is applied to left side, False if on the right side. + cls_token_segment_id (int): int used to represent class token segment. + pad_token_segment_id (int): int used to represent padding segments. + pad_token_id (int): int used to represent the pad token in the tokenized representation. + pad_token_mask_id (int): int used as a mask representing padding. + sequence_a_segment_id (int): int used to represent sequence a segment. + sequence_b_segment_id (int): int used to represent sequence b segment. + sep_token_extra (bool): True for extra separators (e.g., ""), false otherwise. + + """ + + max_seq_length: int + cls_token_at_end: bool + pad_on_left: bool + cls_token_segment_id: int + pad_token_segment_id: int + pad_token_id: int + pad_token_mask_id: int + sequence_a_segment_id: int + sequence_b_segment_id: int + sep_token_extra: bool + + +class BatchMixin(ExtendedDataClassMixin): + def to(self, device, non_blocking=False, copy=False): + # noinspection PyArgumentList + return self.__class__( + **{ + k: self._val_to_device(v=v, device=device, non_blocking=non_blocking, copy=copy,) + for k, v in self.to_dict().items() + } + ) + + @classmethod + def _val_to_device(cls, v, device, non_blocking=False, copy=False): + if isinstance(v, torch.Tensor): + return v.to(device=device, non_blocking=non_blocking, copy=copy) + else: + return v + + def __len__(self): + return len(getattr(self, self.get_fields()[0])) + + +class BaseExample(ExtendedDataClassMixin): + def tokenize(self, tokenizer): + raise NotImplementedError + + +class BaseTokenizedExample(ExtendedDataClassMixin): + def featurize(self, tokenizer, feat_spec: FeaturizationSpec): + raise NotImplementedError + + +class BaseDataRow(ExtendedDataClassMixin): + pass + + +class BaseBatch(BatchMixin, ExtendedDataClassMixin): + @classmethod + def from_data_rows(cls, data_row_ls: list): + raise NotImplementedError + + +def data_row_collate_fn(batch): + assert isinstance(batch[0], BaseDataRow) + + +class TaskTypes(Enum): + CLASSIFICATION = 1 + REGRESSION = 2 + SPAN_COMPARISON_CLASSIFICATION = 3 + MULTIPLE_CHOICE = 4 + SPAN_CHOICE_PROB_TASK = 5 + SQUAD_STYLE_QA = 6 + TAGGING = 7 + MASKED_LANGUAGE_MODELING = 8 + EMBEDDING = 9 + MULTI_LABEL_SPAN_CLASSIFICATION = 10 + SPAN_PREDICTION = 11 + UNDEFINED = -1 + + +class BatchTuple(NamedTuple): + batch: BatchMixin + metadata: dict + + def to(self, device, non_blocking=False, copy=False): + return BatchTuple( + batch=self.batch.to(device=device, non_blocking=non_blocking, copy=copy,), + metadata=self.metadata, + ) + + +def metadata_collate_fn(metadata: list): + return {k: [d[k] for d in metadata] for k in metadata[0].keys()} + + +def flat_collate_fn(batch): + elem = batch[0] + if isinstance(elem, (np.ndarray, int, float, str)): + return dataloader.default_collate(batch) + elif isinstance(elem, (list, dict, set)): + # Don't do anything to list of lists + return batch + else: + raise TypeError(type(elem)) + + +class Task: + Example = NotImplemented + TokenizedExample = NotImplemented + DataRow = NotImplemented + Batch = NotImplemented + + TASK_TYPE = NotImplemented + + def __init__(self, name: str, path_dict: dict): + self.name = name + self.path_dict = path_dict + + @property + def train_path(self): + return self.path_dict["train"] + + @property + def val_path(self): + return self.path_dict["val"] + + @property + def test_path(self): + return self.path_dict["test"] + + @classmethod + def collate_fn(cls, batch): + # cls.collate_fn + elem = batch[0] + if isinstance(elem, Mapping): # dict + assert set(elem.keys()) == {"data_row", "metadata"} + data_rows = [x["data_row"] for x in batch] + metadata = [x["metadata"] for x in batch] + collated_data_rows = { + key: flat_collate_fn([getattr(d, key) for d in data_rows]) + for key in data_rows[0].to_dict() + } + collated_metadata = metadata_collate_fn(metadata) + combined = combine_dicts([collated_data_rows, collated_metadata]) + batch_dict = {} + for field, field_type in cls.Batch.get_annotations().items(): + batch_dict[field] = combined.pop(field) + if field_type == torch.FloatTensor: + # Ensure that floats stay as float32 + batch_dict[field] = batch_dict[field].float() + out_batch = cls.Batch(**batch_dict) + remainder = combined + return out_batch, remainder + else: + raise TypeError(f"Unknown type for collate_fn {type(elem)}") + + +class SuperGlueMixin: + """Mixin for :class:`jiant.tasks.core.Task`s in the `SuperGLUE`_ + benchmark. + """ + + @classmethod + def super_glue_format_preds(cls, pred_dict: Dict): + """Tasks in the SuperGLUE benchmark must implement this method to return + predictions in the expected SuperGLUE format. This function is expect to + return a List[Dict] with each Dict value in the format expected by the + SuperGLUE benchmark submission grader. + + Args: + pred_dict (Dict): Dictionary mapping "preds" to List of label ids + and + "guids" to List of example ids + + Raises: + NotImplementedError + """ + raise NotImplementedError() + + +class GlueMixin: + """Mixin for :class:`jiant.tasks.core.Task`s in the `GLUE`_ + benchmark. + """ + + @classmethod + def get_glue_preds(cls, pred_dict: Dict): + """Returns a tuple of (index, prediction) for GLUE benchmark submission. + + Args: + pred_dict (Dict): Dictionary mapping "preds" to label ids and "guids" + to example ids + + Returns: + (tuple): tuple containing: + indexes (List[int]): example ids + predictions (List[str]): prediction labels (in original task + format) + """ + indexes = [] + predictions = [] + for pred, guid in zip(list(pred_dict["preds"]), list(pred_dict["guids"])): + indexes.append(int(guid.split("-")[1])) + predictions.append(str(cls.LABELS[pred]).lower()) + return (indexes, predictions) diff --git a/jiant/tasks/edge_probing.py b/jiant/tasks/edge_probing.py deleted file mode 100644 index 7201f3988..000000000 --- a/jiant/tasks/edge_probing.py +++ /dev/null @@ -1,387 +0,0 @@ -"""Task definitions for edge probing.""" -import collections -import itertools -import logging as log -import os -import torch -from typing import Dict, Iterable, List, Sequence, Type - -# Fields for instance processing -from allennlp.data import Instance -from allennlp.data.fields import ListField, MetadataField, SpanField -from allennlp.training.metrics import BooleanAccuracy, F1Measure - -from jiant.allennlp_mods.correlation import FastMatthews -from jiant.allennlp_mods.multilabel_field import MultiLabelField -from jiant.utils import utils -from jiant.tasks.registry import register_task # global task registry -from jiant.tasks.tasks import Task, sentence_to_text_field - -## -# Class definitions for edge probing. See below for actual task registration. - - -class EdgeProbingTask(Task): - """ Generic class for fine-grained edge probing. - - Acts as a classifier, but with multiple targets for each input text. - - Targets are of the form (span1, span2, label), where span1 and span2 are - half-open token intervals [i, j). - - Subclass this for each dataset, or use register_task with appropriate kw - args. - """ - - @property - def _tokenizer_suffix(self): - """ Suffix to make sure we use the correct source files, - based on the given tokenizer. - """ - if self.tokenizer_name.startswith("nyu-mll/"): - return ".retokenized." + self.tokenizer_name.replace("/", ".") - elif self.tokenizer_name: - return ".retokenized." + self.tokenizer_name - else: - return "" - - def tokenizer_is_supported(self, tokenizer_name): - """ Check if the tokenizer is supported for this task. """ - # Assume all tokenizers supported; if retokenized data not found - # for this particular task, we'll just crash on file loading. - return True - - def __init__( - self, - path: str, - max_seq_len: int, - name: str, - label_file: str = None, - files_by_split: Dict[str, str] = None, - single_sided: bool = False, - **kw, - ): - """Construct an edge probing task. - - path, max_seq_len, and name are passed by the code in preprocess.py; - remaining arguments should be provided by a subclass constructor or via - @register_task. - - Args: - path: data directory - max_seq_len: maximum sequence length (currently ignored) - name: task name - label_file: relative path to labels file - files_by_split: split name ('train', 'val', 'test') mapped to - relative filenames (e.g. 'train': 'train.json') - single_sided: if true, only use span1. - """ - super().__init__(name, **kw) - - assert label_file is not None - assert files_by_split is not None - self._files_by_split = { - split: os.path.join(path, fname) + self._tokenizer_suffix - for split, fname in files_by_split.items() - } - self.path = path - self.label_file = os.path.join(self.path, label_file) - self.max_seq_len = max_seq_len - self.single_sided = single_sided - - # Placeholders; see self.load_data() - self._iters_by_split = None - self.all_labels = None - self.n_classes = None - - # see add_task_label_namespace in preprocess.py - self._label_namespace = self.name + "_labels" - - # Scorers - self.mcc_scorer = FastMatthews() - self.acc_scorer = BooleanAccuracy() # binary accuracy - self.f1_scorer = F1Measure(positive_label=1) # binary F1 overall - self.val_metric = "%s_f1" % self.name # TODO: switch to MCC? - self.val_metric_decreases = False - - def get_all_labels(self) -> List[str]: - return self.all_labels - - @classmethod - def _stream_records(cls, filename): - skip_ctr = 0 - total_ctr = 0 - for record in utils.load_json_data(filename): - total_ctr += 1 - # Skip records with empty targets. - # TODO(ian): don't do this if generating negatives! - if not record.get("targets", None): - skip_ctr += 1 - continue - yield record - log.info( - "Read=%d, Skip=%d, Total=%d from %s", - total_ctr - skip_ctr, - skip_ctr, - total_ctr, - filename, - ) - - @staticmethod - def merge_preds(record: Dict, preds: Dict) -> Dict: - """ Merge predictions into record, in-place. - - List-valued predictions should align to targets, - and are attached to the corresponding target entry. - - Non-list predictions are attached to the top-level record. - """ - record["preds"] = {} - for target in record["targets"]: - target["preds"] = {} - for key, val in preds.items(): - if isinstance(val, list): - assert len(val) == len(record["targets"]) - for i, target in enumerate(record["targets"]): - target["preds"][key] = val[i] - else: - # non-list predictions, attach to top-level preds - record["preds"][key] = val - return record - - def load_data(self): - self.all_labels = list(utils.load_lines(self.label_file)) - self.n_classes = len(self.all_labels) - iters_by_split = collections.OrderedDict() - for split, filename in self._files_by_split.items(): - # # Lazy-load using RepeatableIterator. - # loader = functools.partial(utils.load_json_data, - # filename=filename) - # iter = serialize.RepeatableIterator(loader) - iter = list(self._stream_records(filename)) - iters_by_split[split] = iter - self._iters_by_split = iters_by_split - - def update_metrics(self, out, batch): - span_mask = batch["span1s"][:, :, 0] != -1 - logits = out["logits"][span_mask] - labels = batch["labels"][span_mask] - - binary_preds = logits.ge(0).long() # {0,1} - - # Matthews coefficient and accuracy computed on {0,1} labels. - self.mcc_scorer(binary_preds, labels.long()) - self.acc_scorer(binary_preds, labels.long()) - - # F1Measure() expects [total_num_targets, n_classes, 2] - # to compute binarized F1. - binary_scores = torch.stack([-1 * logits, logits], dim=2) - self.f1_scorer(binary_scores, labels) - - def handle_preds(self, preds, batch): - """Unpack preds into varying-length numpy arrays, return the non-masked preds in a list. - - Parameters - ---------- - preds : [batch_size, num_targets, ...] - batch : dict - dict with key "span1s" having val w/ bool Tensor dim [batch_size, num_targets, ...]. - - Returns - ------- - non_masked_preds : list[np.ndarray] - list of of pred np.ndarray selected by the corresponding row of span_mask. - - """ - masks = batch["span1s"][:, :, 0] != -1 - preds = preds.detach().cpu() - masks = masks.detach().cpu() - non_masked_preds = [] - for pred, mask in zip(torch.unbind(preds, dim=0), torch.unbind(masks, dim=0)): - non_masked_preds.append(pred[mask].numpy()) # only non-masked predictions - return non_masked_preds - - def get_split_text(self, split: str): - """ Get split text as iterable of records. - - Split should be one of 'train', 'val', or 'test'. - """ - return self._iters_by_split[split] - - @classmethod - def get_num_examples(cls, split_text): - """ Return number of examples in the result of get_split_text. - - Subclass can override this if data is not stored in column format. - """ - return len(split_text) - - @classmethod - def _make_span_field(cls, s, text_field, offset=1): - return SpanField(s[0] + offset, s[1] - 1 + offset, text_field) - - def make_instance(self, record, idx, indexers, model_preprocessing_interface) -> Type[Instance]: - """Convert a single record to an AllenNLP Instance.""" - tokens = record["text"].split() # already space-tokenized by Moses - tokens = model_preprocessing_interface.boundary_token_fn( - tokens - ) # apply model-appropriate variants of [cls] and [sep]. - text_field = sentence_to_text_field(tokens, indexers) - - d = {} - d["idx"] = MetadataField(idx) - - d["input1"] = text_field - - d["span1s"] = ListField( - [self._make_span_field(t["span1"], text_field, 1) for t in record["targets"]] - ) - if not self.single_sided: - d["span2s"] = ListField( - [self._make_span_field(t["span2"], text_field, 1) for t in record["targets"]] - ) - - # Always use multilabel targets, so be sure each label is a list. - labels = [utils.wrap_singleton_string(t["label"]) for t in record["targets"]] - d["labels"] = ListField( - [ - MultiLabelField( - label_set, label_namespace=self._label_namespace, skip_indexing=False - ) - for label_set in labels - ] - ) - return Instance(d) - - def process_split( - self, records, indexers, model_preprocessing_interface - ) -> Iterable[Type[Instance]]: - """ Process split text into a list of AllenNLP Instances. """ - - def _map_fn(r, idx): - return self.make_instance(r, idx, indexers, model_preprocessing_interface) - - return map(_map_fn, records, itertools.count()) - - def get_sentences(self) -> Iterable[Sequence[str]]: - """ Yield sentences, used to compute vocabulary. """ - for split, iter in self._iters_by_split.items(): - # Don't use test set for vocab building. - if split.startswith("test"): - continue - for record in iter: - yield record["text"].split() - - def get_metrics(self, reset=False): - """Get metrics specific to the task""" - metrics = {} - metrics["mcc"] = self.mcc_scorer.get_metric(reset) - metrics["acc"] = self.acc_scorer.get_metric(reset) - precision, recall, f1 = self.f1_scorer.get_metric(reset) - metrics["precision"] = precision - metrics["recall"] = recall - metrics["f1"] = f1 - return metrics - - -## -# Task definitions. We call the register_task decorator explicitly so that we -# can group these in the code. -## - - -## -# Core probing tasks. as featured in the paper. -## -# Part-of-Speech tagging on OntoNotes. -register_task( - "edges-pos-ontonotes", - rel_path="edges/ontonotes/const/pos", - label_file="labels.txt", - files_by_split={"train": "train.json", "val": "development.json", "test": "test.json"}, - single_sided=True, -)(EdgeProbingTask) -# Constituency labeling (nonterminals) on OntoNotes. -register_task( - "edges-nonterminal-ontonotes", - rel_path="edges/ontonotes/const/nonterminal", - label_file="labels.txt", - files_by_split={"train": "train.json", "val": "development.json", "test": "test.json"}, - single_sided=True, -)(EdgeProbingTask) -# Dependency edge labeling on English Web Treebank (UD). -register_task( - "edges-dep-ud-ewt", - rel_path="edges/dep_ewt", - label_file="labels.txt", - files_by_split={ - "train": "en_ewt-ud-train.json", - "val": "en_ewt-ud-dev.json", - "test": "en_ewt-ud-test.json", - }, -)(EdgeProbingTask) -# Entity type labeling on OntoNotes. -register_task( - "edges-ner-ontonotes", - rel_path="edges/ontonotes/ner", - label_file="labels.txt", - files_by_split={"train": "train.json", "val": "development.json", "test": "test.json"}, - single_sided=True, -)(EdgeProbingTask) -# Semantic role labeling on OntoNotes. -register_task( - "edges-srl-ontonotes", - rel_path="edges/ontonotes/srl", - label_file="labels.txt", - files_by_split={"train": "train.json", "val": "development.json", "test": "test.json"}, -)(EdgeProbingTask) -# Coreference on OntoNotes (single-sentence context). -register_task( - "edges-coref-ontonotes", - rel_path="edges/ontonotes/coref", - label_file="labels.txt", - files_by_split={"train": "train.json", "val": "development.json", "test": "test.json"}, -)(EdgeProbingTask) -# SPR1, as an edge-labeling task (multilabel). -register_task( - "edges-spr1", - rel_path="edges/spr1", - label_file="labels.txt", - files_by_split={"train": "spr1.train.json", "val": "spr1.dev.json", "test": "spr1.test.json"}, -)(EdgeProbingTask) -# SPR2, as an edge-labeling task (multilabel). -register_task( - "edges-spr2", - rel_path="edges/spr2", - label_file="labels.txt", - files_by_split={ - "train": "edges.train.json", - "val": "edges.dev.json", - "test": "edges.test.json", - }, -)(EdgeProbingTask) -# Definite pronoun resolution. Two labels. -register_task( - "edges-dpr", - rel_path="edges/dpr", - label_file="labels.txt", - files_by_split={"train": "train.json", "val": "dev.json", "test": "test.json"}, -)(EdgeProbingTask) -# Relation classification on SemEval 2010 Task8. 19 labels. -register_task( - "edges-rel-semeval", - rel_path="edges/semeval", - label_file="labels.txt", - files_by_split={"train": "train.0.85.json", "val": "dev.json", "test": "test.json"}, -)(EdgeProbingTask) - -## -# New or experimental tasks. -## -# Relation classification on TACRED. 42 labels. -register_task( - "edges-rel-tacred", - rel_path="edges/tacred/rel", - label_file="labels.txt", - files_by_split={"train": "train.json", "val": "dev.json", "test": "test.json"}, -)(EdgeProbingTask) diff --git a/jiant/tasks/evaluate/__init__.py b/jiant/tasks/evaluate/__init__.py new file mode 100644 index 000000000..05f5df05e --- /dev/null +++ b/jiant/tasks/evaluate/__init__.py @@ -0,0 +1 @@ +from .core import * # noqa: F401,F403 diff --git a/jiant/tasks/evaluate/core.py b/jiant/tasks/evaluate/core.py new file mode 100644 index 000000000..ad9cb29df --- /dev/null +++ b/jiant/tasks/evaluate/core.py @@ -0,0 +1,1064 @@ +import itertools +import json +from dataclasses import dataclass + +import numpy as np +import pandas as pd +import seqeval.metrics as seqeval_metrics +import torch +from sklearn.metrics import f1_score, matthews_corrcoef +from scipy.stats import pearsonr, spearmanr +from typing import Dict, List + +import jiant.shared.model_resolution as model_resolution +import jiant.tasks as tasks +import jiant.tasks.lib.templates.squad_style.core as squad_style +import jiant.tasks.lib.templates.squad_style.utils as squad_style_utils +import jiant.tasks.lib.mlqa as mlqa_lib +import jiant.tasks.lib.bucc2018 as bucc2018_lib +import jiant.tasks.lib.tatoeba as tatoeba_lib +from jiant.tasks.lib.templates import mlm as mlm_template +from jiant.utils.python.datastructures import ExtendedDataClassMixin +from jiant.utils.python.io import read_json +from jiant.utils.string_comparing import string_f1_score, exact_match_score + + +@dataclass +class Metrics(ExtendedDataClassMixin): + major: float + minor: Dict + + +class BaseEvaluation: + pass + + +class BaseAccumulator: + def update(self, batch_logits, batch_loss, batch, batch_metadata): + raise NotImplementedError() + + def get_guids(self): + return None + + def get_accumulated(self): + raise NotImplementedError() + + +class BaseEvaluationScheme: + def get_accumulator(self) -> BaseAccumulator: + raise NotImplementedError() + + def get_labels_from_cache_and_examples(self, task, cache, examples): + # Depending on the task, labels may be more easily extracted from + # a cache or raw examples. + # Provide the EvaluationScheme with either, but delegate to another function + # using only one. + raise NotImplementedError() + + def get_preds_from_accumulator(self, task, accumulator): + raise NotImplementedError() + + def compute_metrics_from_accumulator( + self, task, accumulator: BaseAccumulator, tokenizer, labels + ) -> Metrics: + raise NotImplementedError() + + +class ConcatenateLogitsAccumulator(BaseAccumulator): + def __init__(self): + self.logits_list = [] + self.guid_list = [] + + def update(self, batch_logits, batch_loss, batch, batch_metadata): + self.logits_list.append(batch_logits) + batch_guid = batch_metadata.get("guid") + if batch_guid is not None: + self.guid_list.append(batch_guid) + + def get_guids(self): + if self.guid_list: + return np.concatenate(self.guid_list) + else: + return None + + def get_accumulated(self): + all_logits = np.concatenate(self.logits_list) + return all_logits + + +class ConcatenateLossAccumulator(BaseAccumulator): + def __init__(self): + self.loss_list = [] + + def update(self, batch_logits, batch_loss, batch, batch_metadata): + self.loss_list.append(batch_loss) + + def get_accumulated(self): + all_loss = np.array(self.loss_list) + return all_loss + + +class ConcatenateStringListAccumulator(BaseAccumulator): + def __init__(self): + self.str_list = [] + + def update(self, batch_logits, batch_loss, batch, batch_metadata): + bs = len(batch_logits) + span_pred = batch_logits.argmax(axis=1) + pred_token_start, pred_token_end = span_pred[:, 0], span_pred[:, 1] + pred_char_start = batch.token_idx_to_char_idx_start.cpu().numpy()[ + range(bs), pred_token_start + ] + pred_char_end = batch.token_idx_to_char_idx_end.cpu().numpy()[range(bs), pred_token_end] + self.str_list.extend( + [ + s[i1 : i2 + 1] + for i1, i2, s in zip(pred_char_start, pred_char_end, batch.selection_str) + ] + ) + + def get_accumulated(self): + return self.str_list + + +class SpanPredictionF1andEMScheme(BaseEvaluationScheme): + def get_accumulator(self): + return ConcatenateStringListAccumulator() + + def get_labels_from_cache_and_examples(self, task, cache, examples): + return [datum["data_row"].gt_span_str for datum in cache.iter_all()] + + def get_preds_from_accumulator(self, task, accumulator): + return accumulator.get_accumulated() + + @classmethod + def compute_metrics_from_preds_and_labels(cls, preds, labels): + em = sum([exact_match_score(s1, s2) for s1, s2 in zip(preds, labels)]) / len(labels) + f1 = sum([string_f1_score(s1, s2) for s1, s2 in zip(preds, labels)]) / len(labels) + scores = {"f1": f1, "em": em, "avg": (f1 + em) / 2} + return Metrics(major=scores["avg"], minor=scores) + + def compute_metrics_from_accumulator( + self, task, accumulator: ConcatenateStringListAccumulator, tokenizer, labels: list + ) -> Metrics: + preds = self.get_preds_from_accumulator(task=task, accumulator=accumulator) + return self.compute_metrics_from_preds_and_labels(preds=preds, labels=labels) + + +class RecordAccumulator(ConcatenateLogitsAccumulator): + def __init__(self): + super().__init__() + self.entity_strs = [] + self.gold_label_list = [] + + def update(self, batch_logits, batch_loss, batch, batch_metadata): + super().update(batch_logits, batch_loss, batch, batch_metadata) + self.entity_strs.extend(batch.entity_str) + self.gold_label_list.extend(batch.label_set) + + def get_accumulated(self): + return super().get_accumulated(), self.entity_strs + + def get_gold_label_list(self): + return self.gold_label_list + + +class MLMPremaskedAccumulator(BaseAccumulator): + def __init__(self): + self.loss_list = [] + self.logits_list = [] + + def update(self, batch_logits, batch_loss, batch, batch_metadata): + batch_size = len(batch) + # Select the tokens that we do MLM prediction on + masked_tokens_selector = ( + batch.masked_lm_labels.cpu().numpy() != mlm_template.NON_MASKED_TOKEN_LABEL_ID + ) + for i in range(batch_size): + # noinspection PyUnresolvedReferences + self.logits_list.append(batch_logits[i][masked_tokens_selector[i]]) + self.loss_list.append(batch_loss) + + def get_accumulated(self): + return self.loss_list, self.logits_list + + +class TatoebaAccumulator(BaseAccumulator): + def __init__(self): + self.embeddings_list = [] + self.is_english_list = [] + + def update(self, batch_logits, batch_loss, batch, batch_metadata): + self.embeddings_list.append(batch_logits) + self.is_english_list.append(batch.is_english.cpu().numpy()) + + @classmethod + def get_guids(cls): + return None + + def get_accumulated(self): + all_embeddings = np.concatenate(self.embeddings_list) + is_english_arr = np.concatenate(self.is_english_list).astype(bool) + return all_embeddings, is_english_arr + + +class Bucc2018Accumulator(BaseAccumulator): + def __init__(self): + self.embeddings_list = [] + self.is_english_list = [] + self.text_hash_list = [] + self.guid_list = [] + + def update(self, batch_logits, batch_loss, batch, batch_metadata): + self.embeddings_list.append(batch_logits) + self.is_english_list.append(batch.is_english.cpu().numpy()) + self.text_hash_list += batch.text_hash + self.guid_list += batch.guid + + @classmethod + def get_guids(cls): + return None + + def get_accumulated(self): + return { + "all_embeddings": np.concatenate(self.embeddings_list), + "is_english_arr": np.concatenate(self.is_english_list).astype(bool), + "text_hash_list": self.text_hash_list, + "guid_list": self.guid_list, + } + + +class BaseLogitsEvaluationScheme(BaseEvaluationScheme): + def get_accumulator(self): + return ConcatenateLogitsAccumulator() + + def get_labels_from_cache_and_examples(self, task, cache, examples): + return get_label_ids_from_cache(cache=cache) + + def get_preds_from_accumulator(self, task, accumulator): + raise NotImplementedError() + + def compute_metrics_from_accumulator( + self, task, accumulator: ConcatenateLogitsAccumulator, tokenizer, labels: list + ) -> Metrics: + preds = self.get_preds_from_accumulator(task=task, accumulator=accumulator) + return self.compute_metrics_from_preds_and_labels(preds=preds, labels=labels) + + def compute_metrics_from_preds_and_labels(self, preds, labels): + raise NotImplementedError() + + +class SimpleAccuracyEvaluationScheme(BaseLogitsEvaluationScheme): + @classmethod + def get_preds_from_accumulator(cls, task, accumulator): + logits = accumulator.get_accumulated() + return np.argmax(logits, axis=1) + + @classmethod + def compute_metrics_from_preds_and_labels(cls, preds, labels): + # noinspection PyUnresolvedReferences + acc = float((preds == labels).mean()) + return Metrics(major=acc, minor={"acc": acc}) + + +class MultiLabelAccAndF1EvaluationScheme(BaseLogitsEvaluationScheme): + def get_labels_from_cache_and_examples(self, task, cache, examples): + return get_multi_label_ids_from_cache(cache=cache) + + def get_preds_from_accumulator(self, task, accumulator): + logits = accumulator.get_accumulated() + return (logits > 0.5).astype(int) + + @classmethod + def compute_metrics_from_preds_and_labels(cls, preds, labels): + # noinspection PyUnresolvedReferences + acc = float((preds == labels).mean()) + labels = np.array(labels) + minor = { + "acc": acc, + "f1_micro": f1_score(y_true=labels, y_pred=preds, average="micro"), + "acc_and_f1_micro": (acc + f1_score(y_true=labels, y_pred=preds, average="micro")) / 2, + } + return Metrics(major=minor["acc_and_f1_micro"], minor=minor) + + +class AccAndF1EvaluationScheme(BaseLogitsEvaluationScheme): + def get_preds_from_accumulator(self, task, accumulator): + logits = accumulator.get_accumulated() + return np.argmax(logits, axis=1) + + @classmethod + def compute_metrics_from_preds_and_labels(cls, preds, labels): + # noinspection PyUnresolvedReferences + acc = float((preds == labels).mean()) + labels = np.array(labels) + f1 = f1_score(y_true=labels, y_pred=preds) + minor = { + "acc": acc, + "f1": f1, + "acc_and_f1": (acc + f1) / 2, + } + return Metrics(major=minor["acc_and_f1"], minor=minor) + + +class MCCEvaluationScheme(BaseLogitsEvaluationScheme): + def get_preds_from_accumulator(self, task, accumulator): + logits = accumulator.get_accumulated() + return np.argmax(logits, axis=1) + + @classmethod + def compute_metrics_from_preds_and_labels(cls, preds, labels): + mcc = matthews_corrcoef(labels, preds) + return Metrics(major=mcc, minor={"mcc": mcc}) + + +class PearsonAndSpearmanEvaluationScheme(BaseLogitsEvaluationScheme): + def get_labels_from_cache_and_examples(self, task, cache, examples): + return get_label_vals_from_cache(cache=cache) + + def get_preds_from_accumulator(self, task, accumulator): + logits = accumulator.get_accumulated() + return np.squeeze(logits, axis=-1) + + @classmethod + def compute_metrics_from_preds_and_labels(cls, preds, labels): + pearson_corr = float(pearsonr(preds, labels)[0]) + spearman_corr = float(spearmanr(preds, labels)[0]) + minor = { + "pearson": pearson_corr, + "spearmanr": spearman_corr, + "corr": (pearson_corr + spearman_corr) / 2, + } + return Metrics(major=minor["corr"], minor=minor) + + +class MultipleChoiceAccuracyEvaluationScheme(BaseLogitsEvaluationScheme): + def get_accumulator(self): + return ConcatenateLogitsAccumulator() + + @classmethod + def get_labels_from_examples(cls, task, examples): + return get_multiple_choice_label_ids_from_examples(task=task, examples=examples) + + def get_labels_from_cache_and_examples(self, task, cache, examples): + return get_multiple_choice_labels_from_cache(cache=cache) + + def get_preds_from_accumulator(self, task, accumulator): + return SimpleAccuracyEvaluationScheme.get_preds_from_accumulator( + task=task, accumulator=accumulator, + ) + + def compute_metrics_from_preds_and_labels(self, preds, labels): + return SimpleAccuracyEvaluationScheme.compute_metrics_from_preds_and_labels( + preds=preds, labels=labels + ) + + +class CommitmentBankEvaluationScheme(BaseLogitsEvaluationScheme): + def get_preds_from_accumulator(self, task, accumulator): + logits = accumulator.get_accumulated() + return np.argmax(logits, axis=1) + + @classmethod + def compute_metrics_from_preds_and_labels(cls, preds, labels): + # noinspection PyUnresolvedReferences + acc = float((preds == labels).mean()) + labels = np.array(labels) + f11 = f1_score(y_true=labels == 0, y_pred=preds == 0) + f12 = f1_score(y_true=labels == 1, y_pred=preds == 1) + f13 = f1_score(y_true=labels == 2, y_pred=preds == 2) + avg_f1 = mean(f11, f12, f13) + return Metrics( + major=mean(acc, avg_f1), + minor={"acc": acc, "avg_f1": avg_f1, "f11": f11, "f12": f12, "f13": f13}, + ) + + +class MultiRCEvaluationScheme(BaseEvaluationScheme): + def get_accumulator(self): + return ConcatenateLogitsAccumulator() + + @classmethod + def get_labels_from_examples(cls, task, examples): + label_values = get_label_ids(examples=examples, task=task) + question_ids = np.array([example.question_id for example in examples]) + assert len(label_values) == len(question_ids) + return [ + {"label_values": lab, "question_ids": qid} + for lab, qid in zip(label_values, question_ids) + ] + + @classmethod + def get_labels_from_cache(cls, cache): + label_values = [] + question_ids = [] + for datum in cache.iter_all(): + label_values.append(datum["data_row"].label_id) + question_ids.append(datum["data_row"].question_id) + label_values = np.array(label_values) + question_ids = np.array(question_ids) + assert len(label_values) == len(question_ids) + return [ + {"label_values": lab, "question_ids": qid} + for lab, qid in zip(label_values, question_ids) + ] + + def get_labels_from_cache_and_examples(self, task, cache, examples): + return self.get_labels_from_examples(task=task, examples=examples) + + def get_preds_from_accumulator(self, task, accumulator): + logits = accumulator.get_accumulated() + return np.argmax(logits, axis=-1) + + def compute_metrics_from_accumulator( + self, task, accumulator: ConcatenateLogitsAccumulator, tokenizer, labels: list + ) -> Metrics: + preds = self.get_preds_from_accumulator(task=task, accumulator=accumulator) + return self.compute_metrics_from_preds_and_labels(preds=preds, labels=labels,) + + @classmethod + def compute_metrics_from_preds_and_labels(cls, preds, labels): + df = pd.DataFrame(labels) + assert "label_values" in df.columns + assert "question_ids" in df.columns + df["preds"] = preds + # noinspection PyUnresolvedReferences + exact_match = ( + df.groupby("question_ids") + .apply(lambda _: (_["preds"] == _["label_values"]).all()) + .mean() + ) + exact_match = float(exact_match) + f1 = f1_score(y_true=df["label_values"], y_pred=df["preds"]) + return Metrics(major=mean(exact_match, f1), minor={"em": exact_match, "f1": f1},) + + +@dataclass +class RecordLabelData: + passage_idx: int + question_idx: int + entity_str: str + answers_dict: Dict[str, str] + + +class ReCordEvaluationScheme(BaseEvaluationScheme): + def get_accumulator(self): + return RecordAccumulator() + + @classmethod + def get_labels_from_examples(cls, examples): + return [ + RecordLabelData( + passage_idx=example.passage_idx, + question_idx=example.question_idx, + entity_str=example.entity_str, + answers_dict=example.answers_dict, + ) + for example in examples + ] + + @classmethod + def get_labels_from_cache_and_examples(cls, task, cache, examples): + return cls.get_labels_from_examples(examples=examples) + + @classmethod + def get_preds_from_accumulator(cls, task, accumulator): + logits, entity_strs = accumulator.get_accumulated() + guid_list = accumulator.get_guids() + + question_ids = [] + for guid in guid_list: + question_ids.append(guid.split("-")[2]) + + # group logits by question id then reorder for submission + # need question id, logit, and entity_str + # for example, dict of question id to logit and entity_str + max_logits = {} + for logit, entity_str, question_id in zip(logits, entity_strs, question_ids): + if (question_id not in max_logits) or (max_logits[question_id]["logit"][1] < logit[1]): + max_logits[question_id] = {"logit": logit, "entity_str": entity_str} + + # Convert labels of max_logits to prediction format + preds = [] + for question_idx, logit_entity in max_logits.items(): + preds.append({"idx": question_idx, "label": logit_entity["entity_str"]}) + + return preds + + def compute_metrics_from_accumulator( + self, task, accumulator: RecordAccumulator, tokenizer, labels: List + ) -> Metrics: + predictions_dict, metrics = self.compute_preds_and_metrics(task, accumulator) + return metrics + + @classmethod + def compute_preds_and_metrics(cls, task, accumulator): + f1_ls = [] + em_ls = [] + predictions_dict = {} + + preds = cls.get_preds_from_accumulator(task, accumulator) + guid_list = guid_list = accumulator.get_guids() + gold_label_list_of_sets = accumulator.get_gold_label_list() + + question_ids = [] + for guid in guid_list: + question_ids.append(guid.split("-")[2]) + + # Reduce list of gold label sets to a gold label set per question_id + gold_labels = {} + for question_id, gold_label_set in zip(question_ids, gold_label_list_of_sets): + if question_id in gold_labels: + assert gold_label_set == gold_labels[question_id] + else: + gold_labels[question_id] = gold_label_set + + for pred, gold_label_set in zip(preds, gold_labels.values()): + pred_ans = pred["label"] + + # F1 + f1 = cls.metric_max_over_ground_truths(string_f1_score, pred_ans, gold_label_set) + f1_ls.append(f1) + + # EM + em = cls.metric_max_over_ground_truths(exact_match_score, pred_ans, gold_label_set) + em_ls.append(em) + + em = sum(em_ls) / len(em_ls) + f1 = sum(f1_ls) / len(f1_ls) + minor = { + "em": em, + "f1": f1, + "f1_em": (f1 + em) / 2, + } + metrics = Metrics(major=minor["f1_em"], minor=minor,) + return predictions_dict, metrics + + @classmethod + def metric_max_over_ground_truths(cls, metric_fn, prediction, ground_truths): + """Compute max metric between prediction and each ground truth. + From official ReCoRD eval script + """ + scores_for_ground_truths = [] + for ground_truth in ground_truths: + score = metric_fn(prediction, ground_truth) + scores_for_ground_truths.append(score) + return max(scores_for_ground_truths) + + +class CCGEvaluationScheme(BaseEvaluationScheme): + def get_accumulator(self): + return ConcatenateLogitsAccumulator() + + @classmethod + def get_label_ids_from_cache(cls, cache): + return [ + {"label_ids": datum["data_row"].label_ids, "label_mask": datum["data_row"].label_mask} + for datum in cache.iter_all() + ] + + @classmethod + def get_labels_from_cache_and_examples(cls, task, cache, examples): + return cls.get_label_ids_from_cache(cache=cache) + + def get_preds_from_accumulator(self, task, accumulator): + logits = accumulator.get_accumulated() + return np.argmax(logits, axis=-1) + + def compute_metrics_from_accumulator( + self, task, accumulator: ConcatenateLogitsAccumulator, tokenizer, labels: list + ) -> Metrics: + preds = self.get_preds_from_accumulator(task=task, accumulator=accumulator) + return self.compute_metrics_from_preds_and_labels(preds=preds, labels=labels,) + + @classmethod + def compute_metrics_from_preds_and_labels(cls, preds, labels): + label_ids = np.stack([row["label_ids"] for row in labels]) + label_mask = np.stack([row["label_mask"] for row in labels]) + + # Account for smart-truncate + assert (label_mask[:, preds.shape[-1] :] == 0).all() + label_ids = label_ids[:, : preds.shape[-1]] + label_mask = label_mask[:, : preds.shape[-1]] + + bool_mask = label_mask.reshape(-1).astype(bool) + flat_preds = preds.reshape(-1)[bool_mask] + flat_labels = label_ids.reshape(-1)[bool_mask] + return cls.compute_metrics_from_flat_preds_and_labels( + flat_preds=flat_preds, flat_labels=flat_labels, + ) + + @classmethod + def compute_metrics_from_flat_preds_and_labels(cls, flat_preds, flat_labels): + return SimpleAccuracyEvaluationScheme.compute_metrics_from_preds_and_labels( + preds=flat_preds, labels=flat_labels, + ) + + +class F1TaggingEvaluationScheme(BaseEvaluationScheme): + def get_accumulator(self): + return ConcatenateLogitsAccumulator() + + @classmethod + def get_labels_from_cache_and_examples(cls, task, cache, examples): + labels = [] + for datum in cache.iter_all(): + label_mask = datum["data_row"].label_mask.astype(bool) + pos_list = [ + task.ID_TO_LABEL[pos_id] for pos_id in datum["data_row"].label_ids[label_mask] + ] + label = { + "pos_list": pos_list, + "label_mask": label_mask, + } + labels.append(label) + assert len(pos_list) == label_mask.sum() + return labels + + def get_preds_from_accumulator(self, task, accumulator): + logits = accumulator.get_accumulated() + return np.argmax(logits, axis=-1) + + def compute_metrics_from_accumulator( + self, task, accumulator: ConcatenateLogitsAccumulator, tokenizer, labels: list + ) -> Metrics: + preds = self.get_preds_from_accumulator(task=task, accumulator=accumulator) + return self.compute_metrics_from_preds_and_labels(task=task, preds=preds, labels=labels,) + + @classmethod + def compute_metrics_from_preds_and_labels(cls, task, preds, labels): + label_mask = np.stack([row["label_mask"] for row in labels]) + + # Account for smart-truncate + assert (label_mask[:, preds.shape[-1] :] == 0).all() + label_mask = label_mask[:, : preds.shape[-1]] + + labels_for_eval = [label["pos_list"] for label in labels] + preds_for_eval = [] + assert len(labels) == preds.shape[0] + for i in range(len(labels)): + relevant_preds = preds[i][label_mask[i]] + relevant_preds_pos = [task.ID_TO_LABEL[pos_id] for pos_id in relevant_preds] + preds_for_eval.append(relevant_preds_pos) + + minor = { + "precision": seqeval_metrics.precision_score(labels_for_eval, preds_for_eval), + "recall": seqeval_metrics.recall_score(labels_for_eval, preds_for_eval), + "f1": seqeval_metrics.f1_score(labels_for_eval, preds_for_eval), + } + return Metrics(major=minor["f1"], minor=minor,) + + +class SQuADEvaluationScheme(BaseEvaluationScheme): + @classmethod + def get_accumulator(cls) -> BaseAccumulator: + return ConcatenateLogitsAccumulator() + + @classmethod + def get_labels_from_cache(cls, cache): + return [cls.get_label_from_data_row(datum["data_row"]) for datum in cache.iter_all()] + + @classmethod + def get_labels_from_cache_and_examples(cls, task, cache, examples): + return cls.get_labels_from_cache(cache=cache) + + def get_preds_from_accumulator(self, task, accumulator): + raise NotImplementedError("Currently can't be done without access to dataset") + + def compute_metrics_from_accumulator( + self, task, accumulator: BaseAccumulator, tokenizer, labels + ) -> Metrics: + logits = accumulator.get_accumulated() + results, predictions = squad_style.compute_predictions_logits_v3( + data_rows=labels, + logits=logits, + n_best_size=task.n_best_size, + max_answer_length=task.max_answer_length, + do_lower_case=model_resolution.resolve_is_lower_case(tokenizer), + version_2_with_negative=task.version_2_with_negative, + null_score_diff_threshold=task.null_score_diff_threshold, + tokenizer=tokenizer, + ) + if task.version_2_with_negative: + # Return the score after the best thresholds for answering has been selected + return Metrics(major=(results["best_f1"] + results["best_exact"]) / 2, minor=results) + else: + return Metrics(major=(results["f1"] + results["exact"]) / 2, minor=results) + + @classmethod + def get_label_from_data_row(cls, data_row): + return squad_style.PartialDataRow.from_data_row(data_row) + + +class XlingQAEvaluationScheme(BaseEvaluationScheme): + @classmethod + def get_accumulator(cls) -> BaseAccumulator: + return ConcatenateLogitsAccumulator() + + @classmethod + def get_labels_from_cache(cls, cache): + return [cls.get_label_from_data_row(datum["data_row"]) for datum in cache.iter_all()] + + @classmethod + def get_labels_from_cache_and_examples(cls, task, cache, examples): + return cls.get_labels_from_cache(cache=cache) + + def get_preds_from_accumulator(self, task, accumulator): + raise NotImplementedError("Currently can't be done without access to dataset") + + def compute_metrics_from_accumulator( + self, task, accumulator: BaseAccumulator, tokenizer, labels + ) -> Metrics: + logits = accumulator.get_accumulated() + assert isinstance(task, (tasks.TyDiQATask, tasks.XquadTask)) + lang = task.language + results, predictions = squad_style.compute_predictions_logits_v3( + data_rows=labels, + logits=logits, + n_best_size=task.n_best_size, + max_answer_length=task.max_answer_length, + do_lower_case=model_resolution.resolve_is_lower_case(tokenizer), + version_2_with_negative=task.version_2_with_negative, + null_score_diff_threshold=task.null_score_diff_threshold, + skip_get_final_text=(lang == "zh"), + tokenizer=tokenizer, + ) + return Metrics(major=(results["f1"] + results["exact"]) / 2, minor=results,) + + @classmethod + def get_label_from_data_row(cls, data_row): + return squad_style.PartialDataRow.from_data_row(data_row) + + +class MLQAEvaluationScheme(SQuADEvaluationScheme): + def get_preds_from_accumulator(self, task, accumulator): + raise NotImplementedError("Too hard for now, too much handled in one giant lib") + + def compute_metrics_from_accumulator( + self, task, accumulator: BaseAccumulator, tokenizer, labels + ) -> Metrics: + + # Todo: Fix val labels cache + # This is a quick hack + logits = accumulator.get_accumulated() + partial_examples = squad_style.data_rows_to_partial_examples(data_rows=labels) + all_pred_results = squad_style.logits_to_pred_results_list(logits) + assert task.context_language == task.question_language + lang = task.context_language + predictions = squad_style_utils.compute_predictions_logits_v2( + partial_examples=partial_examples, + all_results=all_pred_results, + n_best_size=task.n_best_size, + max_answer_length=task.max_answer_length, + do_lower_case=model_resolution.resolve_is_lower_case(tokenizer), + version_2_with_negative=task.version_2_with_negative, + null_score_diff_threshold=task.null_score_diff_threshold, + tokenizer=tokenizer, + skip_get_final_text=(lang == "zh"), + verbose=True, + ) + dataset = read_json(task.val_path)["data"] + results = mlqa_lib.evaluate(dataset=dataset, predictions=predictions, lang=lang,) + return Metrics(major=(results["f1"] + results["exact_match"]) / 2, minor=results,) + + +class MLMEvaluationScheme(BaseEvaluationScheme): + @classmethod + def get_accumulator(cls) -> BaseAccumulator: + return ConcatenateLossAccumulator() + + def get_labels_from_cache_and_examples(self, task, cache, examples): + # This is a dummy function. There are no external labels. + return [None] + + def get_preds_from_accumulator(self, task, accumulator): + raise NotImplementedError("Not possible") + + def compute_metrics_from_accumulator( + self, task, accumulator: BaseAccumulator, tokenizer, labels + ) -> Metrics: + loss_list = accumulator.get_accumulated() + average_loss = mean(loss_list) + perplexity = np.exp(average_loss) + return Metrics( + # Major = negative perplexity + major=-perplexity, + minor={"perplexity": perplexity}, + ) + + +class MLMPremaskedEvaluationScheme(MLMEvaluationScheme): + @classmethod + def get_accumulator(cls) -> BaseAccumulator: + return MLMPremaskedAccumulator() + + @classmethod + def get_labels_from_cache_and_examples(cls, task, cache, examples): + labels = [] + for datum in cache.iter_all(): + masked_lm_labels = datum["data_row"].masked_lm_labels + labels.append( + masked_lm_labels[masked_lm_labels != mlm_template.NON_MASKED_TOKEN_LABEL_ID] + ) + return labels + + def get_preds_from_accumulator(self, task, accumulator): + _, preds = accumulator.get_accumulated() + return preds + + def compute_metrics_from_accumulator( + self, task, accumulator: BaseAccumulator, tokenizer, labels + ) -> Metrics: + loss_list, _ = accumulator.get_accumulated() + average_loss = mean(loss_list) + perplexity = np.exp(average_loss) + return Metrics( + # Major = negative perplexity + major=-perplexity, + minor={"perplexity": perplexity}, + ) + + +class TatoebaEvaluationScheme(BaseEvaluationScheme): + def get_accumulator(self): + return TatoebaAccumulator() + + def get_labels_from_cache_and_examples(self, task, cache, examples): + return task.get_val_labels() + + def get_preds_from_accumulator(self, task, accumulator): + all_embeddings, is_english_arr = accumulator.get_accumulated() + other_lang_embeddings = all_embeddings[~is_english_arr] + eng_embeddings = all_embeddings[is_english_arr] + predictions = tatoeba_lib.similarity_search( + x=other_lang_embeddings, + y=eng_embeddings, + dim=other_lang_embeddings.shape[-1], + normalize=True, + ).flatten() + return predictions + + def compute_metrics_from_accumulator( + self, task, accumulator: ConcatenateLogitsAccumulator, tokenizer, labels: list + ) -> Metrics: + preds = self.get_preds_from_accumulator(task=task, accumulator=accumulator) + return self.compute_metrics_from_preds_and_labels(preds=preds, labels=labels,) + + @classmethod + def compute_metrics_from_preds_and_labels(cls, preds, labels): + # noinspection PyUnresolvedReferences + acc = (preds == labels).mean() + return Metrics(major=acc, minor={"acc": acc}) + + +class Bucc2018EvaluationScheme(BaseEvaluationScheme): + def get_accumulator(self): + return Bucc2018Accumulator() + + def get_labels_from_cache_and_examples(self, task, cache, examples): + return task.get_val_labels() + + def get_preds_from_accumulator(self, task, accumulator, threshold=0): + accumulated = accumulator.get_accumulated() + is_english_arr = accumulated["is_english_arr"] + all_embeddings = accumulated["all_embeddings"] + guids = accumulated["guid_list"] + text_hash_list = accumulated["text_hash_list"] + other_lang_embeddings = all_embeddings[~is_english_arr] + eng_embeddings = all_embeddings[is_english_arr] + english_guids = [x.split("-", 1)[1] for x in np.array(guids)[is_english_arr]] + other_guids = [x.split("-", 1)[1] for x in np.array(guids)[~is_english_arr]] + + n = len(is_english_arr) + src_inds, _ = bucc2018_lib.get_unique_lines( + [text_hash_list[i] for i in np.arange(n) if not is_english_arr[i]] + ) + trg_inds, _ = bucc2018_lib.get_unique_lines( + [text_hash_list[i] for i in np.arange(n) if is_english_arr[i]] + ) + src_ids_map = bucc2018_lib.create_ids_map(src_inds, other_guids) + trg_ids_map = bucc2018_lib.create_ids_map(trg_inds, english_guids) + + result = bucc2018_lib.mine_bitext( + x=other_lang_embeddings, + y=eng_embeddings, + src_inds=src_inds, + trg_inds=trg_inds, + threshold=threshold, + use_gpu=torch.cuda.is_available(), + ) + # Note: Setting thresholds only available in test script + candidates2score = {} + for score, src_idx, trg_idx in result: + for src_key, trg_key in itertools.product(src_ids_map[src_idx], trg_ids_map[trg_idx]): + candidates2score[src_key, trg_key] = score + return candidates2score + + def compute_metrics_from_accumulator( + self, task, accumulator: ConcatenateLogitsAccumulator, tokenizer, labels: list + ) -> Metrics: + preds = self.get_preds_from_accumulator(task=task, accumulator=accumulator) + return self.compute_metrics_from_preds_and_labels(preds=preds, labels=labels,) + + @classmethod + def compute_metrics_from_preds_and_labels(cls, preds, labels): + labels = [tuple(x.split("\t")) for x in labels] + result = bucc2018_lib.bucc_eval(preds, gold=labels, threshold=None) + return Metrics(major=result["F1"], minor=result,) + + +def get_evaluation_scheme_for_task(task) -> BaseEvaluationScheme: + # TODO: move logic to task? (Issue #52) + if isinstance( + task, + ( + tasks.AdversarialNliTask, + tasks.AbductiveNliTask, + tasks.AcceptabilityDefinitenessTask, + tasks.BoolQTask, + tasks.CopaTask, + tasks.MnliTask, + tasks.PawsXTask, + tasks.QnliTask, + tasks.RteTask, + tasks.SciTailTask, + tasks.SentevalTenseTask, + tasks.SnliTask, + tasks.SstTask, + tasks.WiCTask, + tasks.WnliTask, + tasks.WSCTask, + tasks.XnliTask, + ), + ): + return SimpleAccuracyEvaluationScheme() + elif isinstance(task, tasks.CCGTask): + return CCGEvaluationScheme() + elif isinstance(task, tasks.CommitmentBankTask): + return CommitmentBankEvaluationScheme() + elif isinstance(task, tasks.ColaTask): + return MCCEvaluationScheme() + elif isinstance( + task, + ( + tasks.CommonsenseQATask, + tasks.CosmosQATask, + tasks.SWAGTask, + tasks.HellaSwagTask, + tasks.SocialIQATask, + ), + ): + return MultipleChoiceAccuracyEvaluationScheme() + elif isinstance(task, (tasks.MrpcTask, tasks.QqpTask)): + return AccAndF1EvaluationScheme() + elif isinstance( + task, + ( + tasks.Spr1Task, + tasks.Spr2Task, + tasks.SemevalTask, + tasks.SrlTask, + tasks.NerTask, + tasks.CorefTask, + tasks.DprTask, + tasks.DepTask, + tasks.PosTask, + tasks.NonterminalTask, + ), + ): + return MultiLabelAccAndF1EvaluationScheme() + elif isinstance(task, tasks.ReCoRDTask): + return ReCordEvaluationScheme() + elif isinstance(task, tasks.SquadTask): + return SQuADEvaluationScheme() + elif isinstance(task, (tasks.TyDiQATask, tasks.XquadTask)): + return XlingQAEvaluationScheme() + elif isinstance(task, tasks.MlqaTask): + return MLQAEvaluationScheme() + elif isinstance(task, tasks.MultiRCTask): + return MultiRCEvaluationScheme() + elif isinstance(task, tasks.StsbTask): + return PearsonAndSpearmanEvaluationScheme() + elif isinstance(task, tasks.MLMSimpleTask): + return MLMEvaluationScheme() + elif isinstance(task, (tasks.MLMPremaskedTask, tasks.MLMPretokenizedTask)): + return MLMPremaskedEvaluationScheme() + elif isinstance(task, (tasks.QAMRTask, tasks.QASRLTask)): + return SpanPredictionF1andEMScheme() + elif isinstance(task, (tasks.UdposTask, tasks.PanxTask)): + return F1TaggingEvaluationScheme() + elif isinstance(task, tasks.Bucc2018Task): + return Bucc2018EvaluationScheme() + elif isinstance(task, tasks.TatoebaTask): + return TatoebaEvaluationScheme() + else: + raise KeyError(task) + + +def get_label_ids(task, examples): + return np.array([task.LABEL_TO_ID[example.label] for example in examples]) + + +def get_label_ids_from_data_row(data_row): + return data_row.label_ids + + +def get_multi_label_ids_from_cache(cache): + return np.array( + [get_label_ids_from_data_row(data_row=datum["data_row"]) for datum in cache.iter_all()] + ) + + +def get_label_id_from_data_row(data_row): + return data_row.label_id + + +def get_label_ids_from_cache(cache): + return np.array( + [get_label_id_from_data_row(data_row=datum["data_row"]) for datum in cache.iter_all()] + ) + + +def get_label_vals_from_cache(cache): + return np.array( + [get_label_val_from_data_row(data_row=datum["data_row"]) for datum in cache.iter_all()] + ) + + +def get_label_val_from_data_row(data_row): + return data_row.label + + +def get_multiple_choice_label_ids_from_examples(task, examples): + return np.array([task.CHOICE_BIMAP.a[example.label] for example in examples]) + + +def get_multiple_choice_label_id_from_data_row(data_row): + return data_row.label_id + + +def get_multiple_choice_labels_from_cache(cache): + return np.array( + [ + get_multiple_choice_label_id_from_data_row(data_row=datum["data_row"]) + for datum in cache.iter_all() + ] + ) + + +def mean(*args) -> float: + return float(np.mean(args)) + + +def write_metrics(results, output_path, verbose=True): + results_to_write = {} + if "loss" in results: + results_to_write["loss"] = results["loss"] + if "metrics" in results: + results_to_write["metrics"] = results["metrics"].to_dict() + assert results_to_write + metrics_str = json.dumps(results_to_write, indent=2) + if verbose: + print(metrics_str) + with open(output_path, "w") as f: + f.write(metrics_str) diff --git a/jiant/tasks/lib/__init__.py b/jiant/tasks/lib/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/jiant/tasks/lib/abductive_nli.py b/jiant/tasks/lib/abductive_nli.py new file mode 100644 index 000000000..17f3ae5c5 --- /dev/null +++ b/jiant/tasks/lib/abductive_nli.py @@ -0,0 +1,214 @@ +import numpy as np +import torch +from dataclasses import dataclass +from typing import List + +from jiant.tasks.core import ( + BaseExample, + BaseTokenizedExample, + BaseDataRow, + BatchMixin, + Task, + TaskTypes, +) +from jiant.tasks.lib.templates.shared import ( + labels_to_bimap, + add_cls_token, + create_input_set_from_tokens_and_segments, +) +from jiant.tasks.utils import truncate_sequences +from jiant.utils.python.io import read_json_lines + + +@dataclass +class Example(BaseExample): + guid: str + input_obs1: str + input_hyp1: str + input_hyp2: str + input_obs2: str + label: str + + def tokenize(self, tokenizer): + return TokenizedExample( + guid=self.guid, + input_obs1=tokenizer.tokenize(self.input_obs1), + input_hyp1=tokenizer.tokenize(self.input_hyp1), + input_hyp2=tokenizer.tokenize(self.input_hyp2), + input_obs2=tokenizer.tokenize(self.input_obs2), + label_id=AbductiveNliTask.LABEL_TO_ID[self.label], + ) + + +@dataclass +class TokenizedExample(BaseTokenizedExample): + guid: str + input_obs1: List + input_hyp1: List + input_hyp2: List + input_obs2: List + label_id: int + + def featurize(self, tokenizer, feat_spec): + if feat_spec.sep_token_extra: + maybe_extra_sep = [tokenizer.sep_token] + maybe_extra_sep_segment_id = [feat_spec.sequence_a_segment_id] + special_tokens_count = 6 # CLS, SEP-SEP, SEP-SEP, SEP + else: + maybe_extra_sep = [] + maybe_extra_sep_segment_id = [] + special_tokens_count = 4 # CLS, SEP, SEP, SEP + + input_obs1_a, input_hyp1_a, input_obs2_a = truncate_sequences( + tokens_ls=[self.input_obs1, self.input_hyp1, self.input_obs2], + max_length=feat_spec.max_seq_length - special_tokens_count - 1, + # -1 for self.question + ) + input_obs1_b, input_hyp2_b, input_obs2_b = truncate_sequences( + tokens_ls=[self.input_obs1, self.input_hyp2, self.input_obs2], + max_length=feat_spec.max_seq_length - special_tokens_count - 1, + # -1 for self.question + ) + + unpadded_inputs_1 = add_cls_token( + unpadded_tokens=( + input_obs1_a + + [tokenizer.sep_token] + + maybe_extra_sep + + input_hyp1_a + + [tokenizer.sep_token] + + maybe_extra_sep + + input_obs2_a + + [tokenizer.sep_token] + ), + unpadded_segment_ids=( + # question + sep(s) + [feat_spec.sequence_a_segment_id] * (len(input_obs1_a) + 1) + + maybe_extra_sep_segment_id + # premise + sep(s) + + [feat_spec.sequence_a_segment_id] * (len(input_hyp1_a) + 1) + + maybe_extra_sep_segment_id + # choice + sep + + [feat_spec.sequence_b_segment_id] * (len(input_obs2_a) + 1) + ), + tokenizer=tokenizer, + feat_spec=feat_spec, + ) + + unpadded_inputs_2 = add_cls_token( + unpadded_tokens=( + input_obs1_b + + [tokenizer.sep_token] + + maybe_extra_sep + + input_hyp2_b + + [tokenizer.sep_token] + + maybe_extra_sep + + input_obs2_b + + [tokenizer.sep_token] + ), + unpadded_segment_ids=( + # question + sep(s) + [feat_spec.sequence_a_segment_id] * (len(input_obs1_b) + 1) + + maybe_extra_sep_segment_id + # premise + sep(s) + + [feat_spec.sequence_a_segment_id] * (len(input_hyp2_b) + 1) + + maybe_extra_sep_segment_id + # choice + sep + + [feat_spec.sequence_b_segment_id] * (len(input_obs2_b) + 1) + ), + tokenizer=tokenizer, + feat_spec=feat_spec, + ) + + input_set1 = create_input_set_from_tokens_and_segments( + unpadded_tokens=unpadded_inputs_1.unpadded_tokens, + unpadded_segment_ids=unpadded_inputs_1.unpadded_segment_ids, + tokenizer=tokenizer, + feat_spec=feat_spec, + ) + input_set2 = create_input_set_from_tokens_and_segments( + unpadded_tokens=unpadded_inputs_2.unpadded_tokens, + unpadded_segment_ids=unpadded_inputs_2.unpadded_segment_ids, + tokenizer=tokenizer, + feat_spec=feat_spec, + ) + return DataRow( + guid=self.guid, + input_ids=np.stack([input_set1.input_ids, input_set2.input_ids]), + input_mask=np.stack([input_set1.input_mask, input_set2.input_mask]), + segment_ids=np.stack([input_set1.segment_ids, input_set2.segment_ids]), + label_id=self.label_id, + tokens1=unpadded_inputs_1.unpadded_tokens, + tokens2=unpadded_inputs_2.unpadded_tokens, + ) + + +@dataclass +class DataRow(BaseDataRow): + guid: str + input_ids: np.ndarray # Multiple + input_mask: np.ndarray # Multiple + segment_ids: np.ndarray # Multiple + label_id: int + tokens1: list + tokens2: list + + +@dataclass +class Batch(BatchMixin): + input_ids: torch.LongTensor + input_mask: torch.LongTensor + segment_ids: torch.LongTensor + label_id: torch.LongTensor + tokens1: list + tokens2: list + + +class AbductiveNliTask(Task): + Example = Example + TokenizedExample = Example + DataRow = DataRow + Batch = Batch + + TASK_TYPE = TaskTypes.MULTIPLE_CHOICE + NUM_CHOICES = 2 + LABELS = [1, 2] + LABEL_TO_ID, ID_TO_LABEL = labels_to_bimap(LABELS) + + def get_train_examples(self): + return self._create_examples( + lines=read_json_lines(self.path_dict["train_inputs"]), + labels=self._read_labels(self.path_dict["train_labels"]), + set_type="train", + ) + + def get_val_examples(self): + return self._create_examples( + lines=read_json_lines(self.path_dict["val_inputs"]), + labels=self._read_labels(self.path_dict["val_labels"]), + set_type="val", + ) + + def get_test_examples(self): + raise NotImplementedError() + + @classmethod + def _create_examples(cls, lines, labels, set_type): + examples = [] + for (i, (line, label)) in enumerate(zip(lines, labels)): + examples.append( + Example( + guid="%s-%s" % (set_type, i), + input_obs1=line["obs1"], + input_hyp1=line["hyp1"], + input_hyp2=line["hyp2"], + input_obs2=line["obs2"], + label=label, + ) + ) + return examples + + @classmethod + def _read_labels(cls, path): + with open(path) as f: + return [int(i) for i in f.read().split()] diff --git a/jiant/tasks/lib/acceptability_judgement/__init__.py b/jiant/tasks/lib/acceptability_judgement/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/jiant/tasks/lib/acceptability_judgement/definiteness.py b/jiant/tasks/lib/acceptability_judgement/definiteness.py new file mode 100644 index 000000000..0232d817c --- /dev/null +++ b/jiant/tasks/lib/acceptability_judgement/definiteness.py @@ -0,0 +1,99 @@ +import numpy as np +import pandas as pd +import torch +from dataclasses import dataclass +from typing import List + +from jiant.tasks.core import ( + BaseExample, + BaseTokenizedExample, + BaseDataRow, + BatchMixin, + Task, + TaskTypes, +) +from jiant.tasks.lib.templates.shared import single_sentence_featurize, labels_to_bimap + + +@dataclass +class Example(BaseExample): + guid: str + text: str + label: str + + def tokenize(self, tokenizer): + return TokenizedExample( + guid=self.guid, + text=tokenizer.tokenize(self.text), + label_id=AcceptabilityDefinitenessTask.LABEL_TO_ID[self.label], + ) + + +@dataclass +class TokenizedExample(BaseTokenizedExample): + guid: str + text: List + label_id: int + + def featurize(self, tokenizer, feat_spec): + return single_sentence_featurize( + guid=self.guid, + input_tokens=self.text, + label_id=self.label_id, + tokenizer=tokenizer, + feat_spec=feat_spec, + data_row_class=DataRow, + ) + + +@dataclass +class DataRow(BaseDataRow): + guid: str + input_ids: np.ndarray + input_mask: np.ndarray + segment_ids: np.ndarray + label_id: int + tokens: list + + +@dataclass +class Batch(BatchMixin): + input_ids: torch.LongTensor + input_mask: torch.LongTensor + segment_ids: torch.LongTensor + label_id: torch.LongTensor + tokens: list + + +class AcceptabilityDefinitenessTask(Task): + Example = Example + TokenizedExample = TokenizedExample + DataRow = DataRow + Batch = Batch + + TASK_TYPE = TaskTypes.CLASSIFICATION + LABELS = ["acceptable", "unacceptable"] + LABEL_TO_ID, ID_TO_LABEL = labels_to_bimap(LABELS) + + def get_train_examples(self): + return self._create_examples(path=self.train_path, set_type="train") + + def get_val_examples(self): + return self._create_examples(path=self.val_path, set_type="val") + + def get_test_examples(self): + return self._create_examples(path=self.test_path, set_type="test") + + @classmethod + def _create_examples(cls, path, set_type): + examples = [] + df = pd.read_csv(path, sep="\t", index_col=0, names=["text", "label"]) + for i, row in df.iterrows(): + examples.append( + Example( + guid="%s-%s" % (set_type, i), + text=row.text, + label=row.label if set_type != "test" else cls.LABELS[-1], + ) + ) + return examples diff --git a/jiant/tasks/lib/adversarial_nli.py b/jiant/tasks/lib/adversarial_nli.py new file mode 100644 index 000000000..407a35f7e --- /dev/null +++ b/jiant/tasks/lib/adversarial_nli.py @@ -0,0 +1,103 @@ +import numpy as np +import torch +from dataclasses import dataclass +from typing import List + +from jiant.tasks.core import ( + BaseExample, + BaseTokenizedExample, + BaseDataRow, + BatchMixin, + Task, + TaskTypes, +) +from jiant.tasks.lib.templates.shared import double_sentence_featurize, labels_to_bimap +from jiant.utils.python.io import read_json_lines + + +@dataclass +class Example(BaseExample): + guid: str + input_premise: str + input_hypothesis: str + label: str + + def tokenize(self, tokenizer): + return TokenizedExample( + guid=self.guid, + input_premise=tokenizer.tokenize(self.input_premise), + input_hypothesis=tokenizer.tokenize(self.input_hypothesis), + label_id=AdversarialNliTask.LABEL_TO_ID[self.label], + ) + + +@dataclass +class TokenizedExample(BaseTokenizedExample): + guid: str + input_premise: List + input_hypothesis: List + label_id: int + + def featurize(self, tokenizer, feat_spec): + return double_sentence_featurize( + guid=self.guid, + input_tokens_a=self.input_premise, + input_tokens_b=self.input_hypothesis, + label_id=self.label_id, + tokenizer=tokenizer, + feat_spec=feat_spec, + data_row_class=DataRow, + ) + + +@dataclass +class DataRow(BaseDataRow): + guid: str + input_ids: np.ndarray + input_mask: np.ndarray + segment_ids: np.ndarray + label_id: int + tokens: list + + +@dataclass +class Batch(BatchMixin): + input_ids: torch.LongTensor + input_mask: torch.LongTensor + segment_ids: torch.LongTensor + label_id: torch.LongTensor + tokens: list + + +class AdversarialNliTask(Task): + Example = Example + TokenizedExample = Example + DataRow = DataRow + Batch = Batch + + TASK_TYPE = TaskTypes.CLASSIFICATION + LABELS = ["c", "e", "n"] + LABEL_TO_ID, ID_TO_LABEL = labels_to_bimap(LABELS) + + def get_train_examples(self): + return self._create_examples(lines=read_json_lines(self.train_path), set_type="train") + + def get_val_examples(self): + return self._create_examples(lines=read_json_lines(self.val_path), set_type="val") + + def get_test_examples(self): + return self._create_examples(lines=read_json_lines(self.test_path), set_type="test") + + @classmethod + def _create_examples(cls, lines, set_type): + examples = [] + for (i, line) in enumerate(lines): + examples.append( + Example( + guid="%s-%s" % (set_type, i), + input_premise=line["context"], + input_hypothesis=line["hypothesis"], + label=line["label"] if set_type != "test" else cls.LABELS[-1], + ) + ) + return examples diff --git a/jiant/tasks/lib/boolq.py b/jiant/tasks/lib/boolq.py new file mode 100644 index 000000000..705fd06c7 --- /dev/null +++ b/jiant/tasks/lib/boolq.py @@ -0,0 +1,113 @@ +import numpy as np +import torch +from dataclasses import dataclass +from typing import List + +from jiant.tasks.core import ( + BaseExample, + BaseTokenizedExample, + BaseDataRow, + BatchMixin, + SuperGlueMixin, + Task, + TaskTypes, +) +from jiant.tasks.lib.templates.shared import double_sentence_featurize, labels_to_bimap +from jiant.utils.python.io import read_json_lines + + +@dataclass +class Example(BaseExample): + guid: str + input_question: str + input_passage: str + label: str + + def tokenize(self, tokenizer): + return TokenizedExample( + guid=self.guid, + input_question=tokenizer.tokenize(self.input_question), + input_passage=tokenizer.tokenize(self.input_passage), + label_id=BoolQTask.LABEL_TO_ID[self.label], + ) + + +@dataclass +class TokenizedExample(BaseTokenizedExample): + guid: str + input_question: List + input_passage: List + label_id: int + + def featurize(self, tokenizer, feat_spec): + return double_sentence_featurize( + guid=self.guid, + input_tokens_a=self.input_question, + input_tokens_b=self.input_passage, + label_id=self.label_id, + tokenizer=tokenizer, + feat_spec=feat_spec, + data_row_class=DataRow, + ) + + +@dataclass +class DataRow(BaseDataRow): + guid: str + input_ids: np.ndarray + input_mask: np.ndarray + segment_ids: np.ndarray + label_id: int + tokens: list + + +@dataclass +class Batch(BatchMixin): + input_ids: torch.LongTensor + input_mask: torch.LongTensor + segment_ids: torch.LongTensor + label_id: torch.LongTensor + tokens: list + + +class BoolQTask(SuperGlueMixin, Task): + Example = Example + TokenizedExample = Example + DataRow = DataRow + Batch = Batch + + TASK_TYPE = TaskTypes.CLASSIFICATION + LABELS = [False, True] + LABEL_TO_ID, ID_TO_LABEL = labels_to_bimap(LABELS) + + def get_train_examples(self): + return self._create_examples(lines=read_json_lines(self.train_path), set_type="train") + + def get_val_examples(self): + return self._create_examples(lines=read_json_lines(self.val_path), set_type="val") + + def get_test_examples(self): + return self._create_examples(lines=read_json_lines(self.test_path), set_type="test") + + @classmethod + def _create_examples(cls, lines, set_type): + examples = [] + for line in lines: + examples.append( + Example( + # NOTE: BoolQTask.super_glue_format_preds() is dependent on this guid format. + guid="%s-%s" % (set_type, line["idx"]), + input_question=line["question"], + input_passage=line["passage"], + label=line["label"] if set_type != "test" else cls.LABELS[-1], + ) + ) + return examples + + @classmethod + def super_glue_format_preds(cls, pred_dict): + """Reformat this task's raw predictions to have the structure expected by SuperGLUE.""" + lines = [] + for pred, guid in zip(list(pred_dict["preds"]), list(pred_dict["guids"])): + lines.append({"idx": int(guid.split("-")[1]), "label": str(cls.LABELS[pred]).lower()}) + return lines diff --git a/jiant/tasks/lib/bucc2018.py b/jiant/tasks/lib/bucc2018.py new file mode 100644 index 000000000..01c79ab40 --- /dev/null +++ b/jiant/tasks/lib/bucc2018.py @@ -0,0 +1,436 @@ +import hashlib +import numpy as np +import torch +from dataclasses import dataclass +from typing import List + +from jiant.tasks.core import ( + BaseExample, + BaseTokenizedExample, + BaseDataRow, + BatchMixin, + Task, + TaskTypes, +) +from jiant.tasks.lib.templates.shared import ( + construct_single_input_tokens_and_segment_ids, + create_input_set_from_tokens_and_segments, +) +from jiant.utils.python.io import read_file, read_file_lines + + +@dataclass +class Example(BaseExample): + guid: str + is_english: bool + text: str + text_hash: str + + def tokenize(self, tokenizer): + return TokenizedExample( + guid=self.guid, + is_english=self.is_english, + text_tokens=tokenizer.tokenize(self.text), + text_hash=self.text_hash, + ) + + +@dataclass +class TokenizedExample(BaseTokenizedExample): + guid: str + is_english: bool + text_tokens: List + text_hash: str + + def featurize(self, tokenizer, feat_spec): + unpadded_inputs = construct_single_input_tokens_and_segment_ids( + input_tokens=self.text_tokens, tokenizer=tokenizer, feat_spec=feat_spec, + ) + input_set = create_input_set_from_tokens_and_segments( + unpadded_tokens=unpadded_inputs.unpadded_tokens, + unpadded_segment_ids=unpadded_inputs.unpadded_segment_ids, + tokenizer=tokenizer, + feat_spec=feat_spec, + ) + return DataRow( + guid=self.guid, + input_ids=np.array(input_set.input_ids), + input_mask=np.array(input_set.input_mask), + segment_ids=np.array(input_set.segment_ids), + is_english=self.is_english, + tokens=unpadded_inputs.unpadded_tokens, + text_hash=self.text_hash, + ) + + +@dataclass +class DataRow(BaseDataRow): + guid: str + input_ids: np.ndarray + input_mask: np.ndarray + segment_ids: np.ndarray + is_english: bool + tokens: list + text_hash: str + + +@dataclass +class Batch(BatchMixin): + input_ids: torch.LongTensor + input_mask: torch.LongTensor + segment_ids: torch.LongTensor + is_english: torch.BoolTensor + tokens: list + text_hash: list + guid: list + + +class Bucc2018Task(Task): + Example = Example + TokenizedExample = Example + DataRow = DataRow + Batch = Batch + + TASK_TYPE = TaskTypes.EMBEDDING + + def __init__(self, name, path_dict, language): + super().__init__(name=name, path_dict=path_dict) + self.language = language + + def get_train_examples(self): + raise RuntimeError("This task does not support train examples") + + def get_val_examples(self): + return self._get_examples(phase="val") + + def get_test_examples(self): + return self._get_examples(phase="test") + + def get_val_labels(self): + return read_file(self.path_dict["val"]["labels"]).strip().splitlines() + + def _get_examples(self, phase): + eng_examples = self._create_examples( + lines=read_file_lines(self.path_dict[phase]["eng"]), is_english=True, set_type=phase, + ) + other_examples = self._create_examples( + lines=read_file_lines(self.path_dict[phase]["other"]), is_english=False, set_type=phase, + ) + return eng_examples + other_examples + + @classmethod + def _create_examples(cls, lines, is_english, set_type): + examples = [] + for (i, line) in enumerate(lines): + idx, text = line.split("\t") + examples.append( + Example( + guid="%s-%s" % (set_type, idx), + is_english=is_english, + text=text.strip(), + text_hash=hashlib.sha1(text.strip().encode("utf-8")).hexdigest(), + ) + ) + return examples + + +# noinspection PyUnboundLocalVariable +def mine_bitext( + x, + y, + src_inds, + trg_inds, + mode="mine", + retrieval="max", + margin="ratio", + threshold=0, + neighborhood=4, + use_gpu=False, + dist="cosine", + use_shift_embeds=False, +): + # Adapted From: https://github.com/google-research/xtreme/blob/ + # 522434d1aece34131d997a97ce7e9242a51a688a/third_party/utils_retrieve.py + import faiss + + src_orig_inds = np.arange(len(x)) + trg_orig_inds = np.arange(len(y)) + out_ls = [] + + x = unique_embeddings(x, src_inds) + y = unique_embeddings(y, trg_inds) + if dist == "cosine": + faiss.normalize_L2(x) + faiss.normalize_L2(y) + + if use_shift_embeds: + x2y, y2x = shift_embeddings(x, y) + + # calculate knn in both directions + if retrieval != "bwd": + if use_shift_embeds: + # project x to y space, and search k-nn ys for each x + x2y_sim, x2y_ind = knn(x2y, y, min(y.shape[0], neighborhood), use_gpu, dist) + x2y_mean = x2y_sim.mean(axis=1) + else: + x2y_sim, x2y_ind = knn(x, y, min(y.shape[0], neighborhood), use_gpu, dist) + x2y_mean = x2y_sim.mean(axis=1) + + if retrieval != "fwd": + if use_shift_embeds: + y2x_sim, y2x_ind = knn(y2x, x, min(x.shape[0], neighborhood), use_gpu, dist) + y2x_mean = y2x_sim.mean(axis=1) + else: + y2x_sim, y2x_ind = knn(y, x, min(x.shape[0], neighborhood), use_gpu, dist) + y2x_mean = y2x_sim.mean(axis=1) + + # margin function + if margin == "absolute": + # noinspection PyUnusedLocal + def margin(a, b): + return a + + elif margin == "distance": + + def margin(a, b): + return a - b + + else: # margin == 'ratio': + + def margin(a, b): + return a / b + + if mode == "search": + scores = score_candidates(x, y, x2y_ind, x2y_mean, y2x_mean, margin) + best = x2y_ind[np.arange(x.shape[0]), scores.argmax(axis=1)] + + for i in src_inds: + out_ls.append(trg_orig_inds[best[i]]) + + elif mode == "score": + for i, j in zip(src_inds, trg_inds): + s = score(x[i], y[j], x2y_mean[i], y2x_mean[j], margin) + out_ls.append((s, src_orig_inds[i], trg_orig_inds[j])) + + elif mode == "mine": + if use_shift_embeds: + fwd_scores = score_candidates(x2y, y, x2y_ind, x2y_mean, y2x_mean, margin) + bwd_scores = score_candidates(y2x, x, y2x_ind, y2x_mean, x2y_mean, margin) + else: + fwd_scores = score_candidates(x, y, x2y_ind, x2y_mean, y2x_mean, margin) + bwd_scores = score_candidates(y, x, y2x_ind, y2x_mean, x2y_mean, margin) + fwd_best = x2y_ind[np.arange(x.shape[0]), fwd_scores.argmax(axis=1)] + bwd_best = y2x_ind[np.arange(y.shape[0]), bwd_scores.argmax(axis=1)] + if retrieval == "fwd": + for i, j in enumerate(fwd_best): + out_ls.append((fwd_scores[i].max(), src_orig_inds[i], trg_orig_inds[j])) + if retrieval == "bwd": + for j, i in enumerate(bwd_best): + out_ls.append((bwd_scores[j].max(), src_orig_inds[i], trg_orig_inds[j])) + if retrieval == "intersect": + for i, j in enumerate(fwd_best): + if bwd_best[j] == i: + out_ls.append((fwd_scores[i].max(), src_orig_inds[i], trg_orig_inds[j])) + if retrieval == "max": + indices = np.stack( + ( + np.concatenate((np.arange(x.shape[0]), bwd_best)), + np.concatenate((fwd_best, np.arange(y.shape[0]))), + ), + axis=1, + ) + # noinspection PyArgumentList + scores = np.concatenate((fwd_scores.max(axis=1), bwd_scores.max(axis=1))) + seen_src, seen_trg = set(), set() + for i in np.argsort(-scores): + src_ind, trg_ind = indices[i] + if src_ind not in seen_src and trg_ind not in seen_trg: + seen_src.add(src_ind) + seen_trg.add(trg_ind) + if scores[i] > threshold: + out_ls.append((scores[i], src_orig_inds[src_ind], trg_orig_inds[trg_ind])) + return out_ls + + +def bucc_eval(candidates2score, gold, threshold=None): + # Adapted From: https://github.com/google-research/xtreme/blob/ + # 522434d1aece34131d997a97ce7e9242a51a688a/third_party/utils_retrieve.py + if threshold is not None: + print(" - using threshold {}".format(threshold)) + else: + threshold = bucc_optimize(candidates2score, gold) + + gold = set(gold) + bitexts = bucc_extract(candidates2score, threshold) + ncorrect = len(gold.intersection(bitexts)) + if ncorrect > 0: + precision = ncorrect / len(bitexts) + recall = ncorrect / len(gold) + f1 = 2 * precision * recall / (precision + recall) + else: + precision = recall = f1 = 0 + return { + "best-threshold": threshold, + "precision": precision, + "recall": recall, + "F1": f1, + } + + +def bucc_optimize(candidate2score, gold): + # Adapted From: https://github.com/google-research/xtreme/blob/ + # 522434d1aece34131d997a97ce7e9242a51a688a/third_party/utils_retrieve.py + items = sorted(candidate2score.items(), key=lambda x: -x[1]) + ngold = len(gold) + nextract = ncorrect = 0 + threshold = 0 + best_f1 = 0 + for i in range(len(items)): + nextract += 1 + if items[i][0] in gold: + ncorrect += 1 + if ncorrect > 0: + precision = ncorrect / nextract + recall = ncorrect / ngold + f1 = 2 * precision * recall / (precision + recall) + if f1 > best_f1: + best_f1 = f1 + threshold = (items[i][1] + items[i + 1][1]) / 2 + return threshold + + +def bucc_extract(cand2score, th): + # Adapted From: https://github.com/google-research/xtreme/blob/ + # 522434d1aece34131d997a97ce7e9242a51a688a/third_party/utils_retrieve.py + bitexts = [] + for (src, trg), score_ in cand2score.items(): + if score_ >= th: + bitexts.append((src, trg)) + return bitexts + + +def unique_embeddings(emb, ind): + # Adapted From: https://github.com/google-research/xtreme/blob/ + # 522434d1aece34131d997a97ce7e9242a51a688a/third_party/utils_retrieve.py + aux = {j: i for i, j in enumerate(ind)} + return emb[[aux[i] for i in range(len(aux))]] + + +def shift_embeddings(x, y): + # Adapted From: https://github.com/google-research/xtreme/blob/ + # 522434d1aece34131d997a97ce7e9242a51a688a/third_party/utils_retrieve.py + delta = x.mean(axis=0) - y.mean(axis=0) + x2y = x - delta + y2x = y + delta + return x2y, y2x + + +def score_candidates(x, y, candidate_inds, fwd_mean, bwd_mean, margin, dist="cosine"): + # Adapted From: https://github.com/google-research/xtreme/blob/ + # 522434d1aece34131d997a97ce7e9242a51a688a/third_party/utils_retrieve.py + scores = np.zeros(candidate_inds.shape) + for i in range(scores.shape[0]): + for j in range(scores.shape[1]): + k = candidate_inds[i, j] + scores[i, j] = score(x[i], y[k], fwd_mean[i], bwd_mean[k], margin, dist) + return scores + + +def score(x, y, fwd_mean, bwd_mean, margin, dist="cosine"): + # Adapted From: https://github.com/google-research/xtreme/blob/ + # 522434d1aece34131d997a97ce7e9242a51a688a/third_party/utils_retrieve.py + if dist == "cosine": + return margin(x.dot(y), (fwd_mean + bwd_mean) / 2) + else: + l2 = ((x - y) ** 2).sum() + sim = 1 / (1 + l2) + return margin(sim, (fwd_mean + bwd_mean) / 2) + + +def knn(x, y, k, use_gpu, dist="cosine"): + # Adapted From: https://github.com/google-research/xtreme/blob/ + # 522434d1aece34131d997a97ce7e9242a51a688a/third_party/utils_retrieve.py + return knn_gpu(x, y, k) if use_gpu else knn_cpu(x, y, k, dist) + + +def knn_gpu(x, y, k, mem=5 * 1024 * 1024 * 1024): + # Adapted From: https://github.com/google-research/xtreme/blob/ + # 522434d1aece34131d997a97ce7e9242a51a688a/third_party/utils_retrieve.py + import faiss + + dim = x.shape[1] + batch_size = mem // (dim * 4) + sim = np.zeros((x.shape[0], k), dtype=np.float32) + ind = np.zeros((x.shape[0], k), dtype=np.int64) + for xfrom in range(0, x.shape[0], batch_size): + xto = min(xfrom + batch_size, x.shape[0]) + bsims, binds = [], [] + for yfrom in range(0, y.shape[0], batch_size): + yto = min(yfrom + batch_size, y.shape[0]) + idx = faiss.IndexFlatIP(dim) + idx = faiss.index_cpu_to_all_gpus(idx) + idx.add(y[yfrom:yto]) + bsim, bind = idx.search(x[xfrom:xto], min(k, yto - yfrom)) + bsims.append(bsim) + binds.append(bind + yfrom) + del idx + bsims = np.concatenate(bsims, axis=1) + binds = np.concatenate(binds, axis=1) + aux = np.argsort(-bsims, axis=1) + for i in range(xfrom, xto): + for j in range(k): + sim[i, j] = bsims[i - xfrom, aux[i - xfrom, j]] + ind[i, j] = binds[i - xfrom, aux[i - xfrom, j]] + return sim, ind + + +def knn_cpu(x, y, k, dist="cosine"): + # Adapted From: https://github.com/google-research/xtreme/blob/ + # 522434d1aece34131d997a97ce7e9242a51a688a/third_party/utils_retrieve.py + import faiss + + # x: query, y: database + dim = x.shape[1] + if dist == "cosine": + idx = faiss.IndexFlatIP(dim) + else: + idx = faiss.IndexFlatL2(dim) + idx.add(y) + sim, ind = idx.search(x, k) + + if dist != "cosine": + sim = 1 / (1 + sim) + return sim, ind + + +def get_unique_lines(text_hashes): + """Get the unique lines out of a list of text-hashes + + Args: + text_hashes (list): A list of (hashes of) strings + + Returns: + unique_indices (List): List (of the same length as text_hashes) indicating, for each + element of text_hash, the index of the corresponding entry in + unique_text_hashes + (i.e. "Which unique text-hash does this correspond to?") + unique_text_hashes (List): List of unique elements of text_hashes + """ + unique_text_hashes = [] + unique_indices = [] + unique_lookup = {} + for text_hash in text_hashes: + if text_hash not in unique_lookup: + unique_lookup[text_hash] = len(unique_lookup) + unique_text_hashes.append(text_hash) + unique_indices.append(unique_lookup[text_hash]) + return unique_indices, unique_text_hashes + + +def create_ids_map(inds, guids): + ids_map = {} + for guid, idx in zip(guids, inds): + if idx not in ids_map: + ids_map[idx] = [] + ids_map[idx].append(guid) + return ids_map diff --git a/jiant/tasks/lib/ccg.py b/jiant/tasks/lib/ccg.py new file mode 100644 index 000000000..c468c03e8 --- /dev/null +++ b/jiant/tasks/lib/ccg.py @@ -0,0 +1,164 @@ +import numpy as np +import torch +from dataclasses import dataclass +from typing import List, Union + +from jiant.tasks.core import ( + BaseExample, + BaseTokenizedExample, + BaseDataRow, + BatchMixin, + Task, + TaskTypes, +) +from jiant.tasks.lib.templates.shared import ( + labels_to_bimap, + create_input_set_from_tokens_and_segments, + construct_single_input_tokens_and_segment_ids, + pad_single_with_feat_spec, +) +from jiant.tasks.lib.templates import hacky_tokenization_matching as tokenization_utils +from jiant.utils.python.io import read_json + + +@dataclass +class Example(BaseExample): + guid: str + text: str + tag_ids: List[int] + + def tokenize(self, tokenizer): + tokenized = tokenizer.tokenize(self.text) + split_text = self.text.split(" ") # CCG data is space-tokenized + input_flat_stripped = tokenization_utils.input_flat_strip(split_text) + flat_stripped, indices = tokenization_utils.delegate_flat_strip( + tokens=tokenized, tokenizer=tokenizer, return_indices=True, + ) + assert flat_stripped == input_flat_stripped + positions = tokenization_utils.map_tags_to_token_position( + flat_stripped=flat_stripped, indices=indices, split_text=split_text, + ) + labels, label_mask = tokenization_utils.convert_mapped_tags( + positions=positions, tag_ids=self.tag_ids, length=len(tokenized), + ) + + return TokenizedExample( + guid=self.guid, + text=tokenizer.tokenize(self.text), + labels=labels, + label_mask=label_mask, + ) + + +@dataclass +class TokenizedExample(BaseTokenizedExample): + guid: str + text: List + labels: List[Union[int, None]] + label_mask: List[int] + + def featurize(self, tokenizer, feat_spec): + unpadded_inputs = construct_single_input_tokens_and_segment_ids( + input_tokens=self.text, tokenizer=tokenizer, feat_spec=feat_spec, + ) + input_set = create_input_set_from_tokens_and_segments( + unpadded_tokens=unpadded_inputs.unpadded_tokens, + unpadded_segment_ids=unpadded_inputs.unpadded_segment_ids, + tokenizer=tokenizer, + feat_spec=feat_spec, + ) + + # Replicate padding / additional tokens for the label ids and mask + if feat_spec.sep_token_extra: + label_suffix = [None, None] + mask_suffix = [0, 0] + special_tokens_count = 3 # CLS, SEP-SEP + else: + label_suffix = [None] + mask_suffix = [0] + special_tokens_count = 2 # CLS, SEP + unpadded_labels = ( + [None] + self.labels[: feat_spec.max_seq_length - special_tokens_count] + label_suffix + ) + unpadded_labels = [i if i is not None else -1 for i in unpadded_labels] + unpadded_label_mask = ( + [0] + self.label_mask[: feat_spec.max_seq_length - special_tokens_count] + mask_suffix + ) + + padded_labels = pad_single_with_feat_spec( + ls=unpadded_labels, feat_spec=feat_spec, pad_idx=-1, + ) + padded_label_mask = pad_single_with_feat_spec( + ls=unpadded_label_mask, feat_spec=feat_spec, pad_idx=0, + ) + + return DataRow( + guid=self.guid, + input_ids=np.array(input_set.input_ids), + input_mask=np.array(input_set.input_mask), + segment_ids=np.array(input_set.segment_ids), + label_ids=np.array(padded_labels), + label_mask=np.array(padded_label_mask), + tokens=unpadded_inputs.unpadded_tokens, + ) + + +@dataclass +class DataRow(BaseDataRow): + guid: str + input_ids: np.ndarray + input_mask: np.ndarray + segment_ids: np.ndarray + label_ids: np.ndarray + label_mask: np.ndarray + tokens: list + + +@dataclass +class Batch(BatchMixin): + input_ids: torch.LongTensor + input_mask: torch.LongTensor + segment_ids: torch.LongTensor + label_ids: torch.LongTensor + label_mask: torch.LongTensor + tokens: list + + +class CCGTask(Task): + Example = Example + TokenizedExample = Example + DataRow = DataRow + Batch = Batch + + TASK_TYPE = TaskTypes.TAGGING + LABELS = range(1363) + LABEL_TO_ID, ID_TO_LABEL = labels_to_bimap(LABELS) + + @property + def num_labels(self): + return 1363 + + def get_train_examples(self): + return self._create_examples(path=self.train_path, set_type="train") + + def get_val_examples(self): + return self._create_examples(self.val_path, set_type="val") + + def get_test_examples(self): + return self._create_examples(path=self.test_path, set_type="test") + + def get_tags_to_id(self): + tags_to_id = read_json(self.path_dict["tags_to_id"]) + tags_to_id = {k: int(v) for k, v in tags_to_id.items()} + return tags_to_id + + def _create_examples(self, path, set_type): + tags_to_id = self.get_tags_to_id() + examples = [] + with open(path, "r") as f: + for i, line in enumerate(f): + text, tags = line.strip().split("\t") + split_tags = tags.split() + tag_ids = [tags_to_id[tag] for tag in split_tags] + examples.append(Example(guid="%s-%s" % (set_type, i), text=text, tag_ids=tag_ids,)) + return examples diff --git a/jiant/tasks/lib/cola.py b/jiant/tasks/lib/cola.py new file mode 100644 index 000000000..9cadb7242 --- /dev/null +++ b/jiant/tasks/lib/cola.py @@ -0,0 +1,100 @@ +import numpy as np +import torch +from dataclasses import dataclass +from typing import List + +from jiant.tasks.core import ( + BaseExample, + BaseTokenizedExample, + BaseDataRow, + BatchMixin, + GlueMixin, + Task, + TaskTypes, +) +from jiant.tasks.lib.templates.shared import single_sentence_featurize, labels_to_bimap +from jiant.utils.python.io import read_jsonl + + +@dataclass +class Example(BaseExample): + guid: str + text: str + label: str + + def tokenize(self, tokenizer): + return TokenizedExample( + guid=self.guid, + text=tokenizer.tokenize(self.text), + label_id=ColaTask.LABEL_TO_ID[self.label], + ) + + +@dataclass +class TokenizedExample(BaseTokenizedExample): + guid: str + text: List + label_id: int + + def featurize(self, tokenizer, feat_spec): + return single_sentence_featurize( + guid=self.guid, + input_tokens=self.text, + label_id=self.label_id, + tokenizer=tokenizer, + feat_spec=feat_spec, + data_row_class=DataRow, + ) + + +@dataclass +class DataRow(BaseDataRow): + guid: str + input_ids: np.ndarray + input_mask: np.ndarray + segment_ids: np.ndarray + label_id: int + tokens: list + + +@dataclass +class Batch(BatchMixin): + input_ids: torch.LongTensor + input_mask: torch.LongTensor + segment_ids: torch.LongTensor + label_id: torch.LongTensor + tokens: list + + +class ColaTask(GlueMixin, Task): + Example = Example + TokenizedExample = Example + DataRow = DataRow + Batch = Batch + + TASK_TYPE = TaskTypes.CLASSIFICATION + LABELS = ["0", "1"] + LABEL_TO_ID, ID_TO_LABEL = labels_to_bimap(LABELS) + + def get_train_examples(self): + return self._create_examples(lines=read_jsonl(self.train_path), set_type="train") + + def get_val_examples(self): + return self._create_examples(lines=read_jsonl(self.val_path), set_type="val") + + def get_test_examples(self): + return self._create_examples(lines=read_jsonl(self.test_path), set_type="test") + + @classmethod + def _create_examples(cls, lines, set_type): + examples = [] + for (i, line) in enumerate(lines): + examples.append( + Example( + # NOTE: get_glue_preds() is dependent on this guid format. + guid="%s-%s" % (set_type, i), + text=line["text"], + label=line["label"] if set_type != "test" else cls.LABELS[-1], + ) + ) + return examples diff --git a/jiant/tasks/lib/commitmentbank.py b/jiant/tasks/lib/commitmentbank.py new file mode 100644 index 000000000..6317f187d --- /dev/null +++ b/jiant/tasks/lib/commitmentbank.py @@ -0,0 +1,114 @@ +import numpy as np +import torch +from dataclasses import dataclass +from typing import List + +from jiant.tasks.core import ( + BaseExample, + BaseTokenizedExample, + BaseDataRow, + BatchMixin, + SuperGlueMixin, + Task, + TaskTypes, +) +from jiant.tasks.lib.templates.shared import labels_to_bimap, double_sentence_featurize +from jiant.utils.python.io import read_json_lines + + +@dataclass +class Example(BaseExample): + guid: str + input_premise: str + input_hypothesis: str + label: str + + def tokenize(self, tokenizer): + return TokenizedExample( + guid=self.guid, + input_premise=tokenizer.tokenize(self.input_premise), + input_hypothesis=tokenizer.tokenize(self.input_hypothesis), + label_id=CommitmentBankTask.LABEL_TO_ID[self.label], + ) + + +@dataclass +class TokenizedExample(BaseTokenizedExample): + guid: str + input_premise: List + input_hypothesis: List + label_id: int + + def featurize(self, tokenizer, feat_spec): + return double_sentence_featurize( + guid=self.guid, + input_tokens_a=self.input_premise, + input_tokens_b=self.input_hypothesis, + label_id=self.label_id, + tokenizer=tokenizer, + feat_spec=feat_spec, + data_row_class=DataRow, + ) + + +@dataclass +class DataRow(BaseDataRow): + guid: str + input_ids: np.ndarray + input_mask: np.ndarray + segment_ids: np.ndarray + label_id: int + tokens: list + + +@dataclass +class Batch(BatchMixin): + input_ids: torch.LongTensor + input_mask: torch.LongTensor + segment_ids: torch.LongTensor + label_id: torch.LongTensor + tokens: list + + +class CommitmentBankTask(SuperGlueMixin, Task): + Example = Example + TokenizedExample = Example + DataRow = DataRow + Batch = Batch + + TASK_TYPE = TaskTypes.CLASSIFICATION + LABELS = ["neutral", "entailment", "contradiction"] + LABEL_TO_ID, ID_TO_LABEL = labels_to_bimap(LABELS) + + def get_train_examples(self): + return self._create_examples(lines=read_json_lines(self.train_path), set_type="train") + + def get_val_examples(self): + return self._create_examples(lines=read_json_lines(self.val_path), set_type="val") + + def get_test_examples(self): + return self._create_examples(lines=read_json_lines(self.test_path), set_type="test") + + @classmethod + def _create_examples(cls, lines, set_type): + examples = [] + for line in lines: + examples.append( + Example( + # NOTE: CommitmentBankTask.super_glue_format_preds() is + # dependent on this guid format. + guid="%s-%s" % (set_type, line["idx"]), + input_premise=line["premise"], + input_hypothesis=line["hypothesis"], + label=line["label"] if set_type != "test" else cls.LABELS[-1], + ) + ) + return examples + + @classmethod + def super_glue_format_preds(cls, pred_dict): + """Reformat this task's raw predictions to have the structure expected by SuperGLUE.""" + lines = [] + for pred, guid in zip(list(pred_dict["preds"]), list(pred_dict["guids"])): + lines.append({"idx": int(guid.split("-")[1]), "label": cls.LABELS[pred]}) + return lines diff --git a/jiant/tasks/lib/commonsenseqa.py b/jiant/tasks/lib/commonsenseqa.py new file mode 100644 index 000000000..b362002db --- /dev/null +++ b/jiant/tasks/lib/commonsenseqa.py @@ -0,0 +1,90 @@ +from dataclasses import dataclass + +from jiant.tasks.lib.templates.shared import labels_to_bimap +from jiant.tasks.lib.templates import multiple_choice as mc_template +from jiant.utils.python.io import read_json_lines + + +@dataclass +class Example(mc_template.Example): + @property + def task(self): + return CommonsenseQATask + + +@dataclass +class TokenizedExample(mc_template.TokenizedExample): + pass + + +@dataclass +class DataRow(mc_template.DataRow): + pass + + +@dataclass +class Batch(mc_template.Batch): + pass + + +class CommonsenseQATask(mc_template.AbstractMultipleChoiceTask): + Example = Example + TokenizedExample = Example + DataRow = DataRow + Batch = Batch + + CHOICE_KEYS = ["A", "B", "C", "D", "E"] + CHOICE_TO_ID, ID_TO_CHOICE = labels_to_bimap(CHOICE_KEYS) + NUM_CHOICES = len(CHOICE_KEYS) + + def get_train_examples(self): + return self._create_examples(lines=read_json_lines(self.train_path), set_type="train") + + def get_val_examples(self): + return self._create_examples(lines=read_json_lines(self.val_path), set_type="val") + + def get_test_examples(self): + return self._create_examples(lines=read_json_lines(self.test_path), set_type="test") + + @classmethod + def _create_examples(cls, lines, set_type): + examples = [] + for i, line in enumerate(lines): + examples.append(cls._create_example(raw_example=line, set_type=set_type, i=i,)) + return examples + + @classmethod + def _create_example(cls, raw_example, set_type, i): + # Use heuristic for determining original or NLP format + if isinstance(raw_example["question"], dict): + return cls._create_example_from_original_format( + raw_example=raw_example, set_type=set_type, i=i, + ) + elif isinstance(raw_example["question"], str): + return cls._create_example_from_nlp_format( + raw_example=raw_example, set_type=set_type, i=i, + ) + else: + raise TypeError(raw_example["question"]) + + @classmethod + def _create_example_from_original_format(cls, raw_example, set_type, i): + """Return question and choices from original example format""" + choice_dict = {elem["label"]: elem["text"] for elem in raw_example["question"]["choices"]} + choice_list = [choice_dict[key] for key in cls.CHOICE_KEYS] + return Example( + guid="%s-%s" % (set_type, i), + prompt=raw_example["question"]["stem"], + choice_list=choice_list, + label=raw_example["answerKey"] if set_type != "test" else cls.CHOICE_KEYS[-1], + ) + + @classmethod + def _create_example_from_nlp_format(cls, raw_example, set_type, i): + """Return question and choices from NLP example format""" + return Example( + guid="%s-%s" % (set_type, i), + prompt=raw_example["question"], + choice_list=raw_example["choices"]["text"], + label=raw_example["answerKey"] if set_type != "test" else cls.CHOICE_KEYS[-1], + ) diff --git a/jiant/tasks/lib/copa.py b/jiant/tasks/lib/copa.py new file mode 100644 index 000000000..9bed1c309 --- /dev/null +++ b/jiant/tasks/lib/copa.py @@ -0,0 +1,77 @@ +from dataclasses import dataclass + +from jiant.tasks.lib.templates.shared import labels_to_bimap +from jiant.tasks.lib.templates import multiple_choice as mc_template +from jiant.utils.python.io import read_json_lines +from jiant.tasks.core import SuperGlueMixin + + +@dataclass +class Example(mc_template.Example): + @property + def task(self): + return CopaTask + + +@dataclass +class TokenizedExample(mc_template.TokenizedExample): + pass + + +@dataclass +class DataRow(mc_template.DataRow): + pass + + +@dataclass +class Batch(mc_template.Batch): + pass + + +class CopaTask(SuperGlueMixin, mc_template.AbstractMultipleChoiceTask): + Example = Example + TokenizedExample = Example + DataRow = DataRow + Batch = Batch + + CHOICE_KEYS = [0, 1] + CHOICE_TO_ID, ID_TO_CHOICE = labels_to_bimap(CHOICE_KEYS) + NUM_CHOICES = len(CHOICE_KEYS) + + _QUESTION_DICT = { + "cause": "What was the cause of this?", + "effect": "What happened as a result?", + } + + def get_train_examples(self): + return self._create_examples(lines=read_json_lines(self.train_path), set_type="train") + + def get_val_examples(self): + return self._create_examples(lines=read_json_lines(self.val_path), set_type="val") + + def get_test_examples(self): + return self._create_examples(lines=read_json_lines(self.test_path), set_type="test") + + @classmethod + def _create_examples(cls, lines, set_type): + examples = [] + for line in lines: + question = cls._QUESTION_DICT[line["question"]] + examples.append( + Example( + # NOTE: CopaTask.super_glue_format_preds() is dependent on this guid format. + guid="%s-%s" % (set_type, line["idx"]), + prompt=line["premise"] + " " + question, + choice_list=[line["choice1"], line["choice2"]], + label=line["label"] if set_type != "test" else cls.CHOICE_KEYS[-1], + ) + ) + return examples + + @classmethod + def super_glue_format_preds(cls, pred_dict): + """Reformat this task's raw predictions to have the structure expected by SuperGLUE.""" + lines = [] + for pred, guid in zip(list(pred_dict["preds"]), list(pred_dict["guids"])): + lines.append({"idx": int(guid.split("-")[1]), "label": cls.CHOICE_KEYS[pred]}) + return lines diff --git a/jiant/tasks/lib/cosmosqa.py b/jiant/tasks/lib/cosmosqa.py new file mode 100644 index 000000000..edffc0599 --- /dev/null +++ b/jiant/tasks/lib/cosmosqa.py @@ -0,0 +1,67 @@ +import pandas as pd +from dataclasses import dataclass + +from jiant.tasks.lib.templates.shared import labels_to_bimap +from jiant.tasks.lib.templates import multiple_choice as mc_template + + +@dataclass +class Example(mc_template.Example): + @property + def task(self): + return CosmosQATask + + +@dataclass +class TokenizedExample(mc_template.TokenizedExample): + pass + + +@dataclass +class DataRow(mc_template.DataRow): + pass + + +@dataclass +class Batch(mc_template.Batch): + pass + + +class CosmosQATask(mc_template.AbstractMultipleChoiceTask): + Example = Example + TokenizedExample = Example + DataRow = DataRow + Batch = Batch + + CHOICE_KEYS = [0, 1, 2, 3] + CHOICE_TO_ID, ID_TO_CHOICE = labels_to_bimap(CHOICE_KEYS) + NUM_CHOICES = len(CHOICE_KEYS) + + def get_train_examples(self): + return self._create_examples(path=self.train_path, set_type="train") + + def get_val_examples(self): + return self._create_examples(path=self.val_path, set_type="val") + + def get_test_examples(self): + return self._create_examples(path=self.test_path, set_type="test") + + @classmethod + def _create_examples(cls, path, set_type): + if path.endswith(".csv"): + df = pd.read_csv(path) + elif path.endswith(".jsonl"): + df = pd.read_json(path, lines=True) + else: + raise RuntimeError("Format not supported") + examples = [] + for i, row in enumerate(df.itertuples()): + examples.append( + Example( + guid="%s-%s" % (set_type, i), + prompt=row.context + " " + row.question, + choice_list=[row.answer0, row.answer1, row.answer2, row.answer3], + label=row.label if set_type != "test" else cls.CHOICE_KEYS[-1], + ) + ) + return examples diff --git a/jiant/tasks/lib/edge_probing/coref.py b/jiant/tasks/lib/edge_probing/coref.py new file mode 100644 index 000000000..b72cb2230 --- /dev/null +++ b/jiant/tasks/lib/edge_probing/coref.py @@ -0,0 +1,74 @@ +"""Coreference Edge Probing task. + +Task source paper: https://arxiv.org/pdf/1905.06316.pdf. +Task data prep directions: https://github.com/nyu-mll/jiant/blob/master/probing/data/README.md. + +""" +from dataclasses import dataclass + +from jiant.tasks.lib.templates.shared import labels_to_bimap +from jiant.tasks.lib.templates import edge_probing_two_span +from jiant.utils.python.io import read_json_lines + + +@dataclass +class Example(edge_probing_two_span.Example): + @property + def task(self): + return CorefTask + + +@dataclass +class TokenizedExample(edge_probing_two_span.TokenizedExample): + pass + + +@dataclass +class DataRow(edge_probing_two_span.DataRow): + pass + + +@dataclass +class Batch(edge_probing_two_span.Batch): + pass + + +class CorefTask(edge_probing_two_span.AbstractProbingTask): + Example = Example + TokenizedExample = TokenizedExample + DataRow = DataRow + Batch = Batch + + LABELS = ["0", "1"] + LABEL_TO_ID, ID_TO_LABEL = labels_to_bimap(LABELS) + + @property + def num_spans(self): + return 2 + + def get_train_examples(self): + return self._create_examples(lines=read_json_lines(self.train_path), set_type="train") + + def get_val_examples(self): + return self._create_examples(lines=read_json_lines(self.val_path), set_type="val") + + def get_test_examples(self): + return self._create_examples(lines=read_json_lines(self.test_path), set_type="test") + + @classmethod + def _create_examples(cls, lines, set_type): + examples = [] + for (line_num, line) in enumerate(lines): + for (target_num, target) in enumerate(line["targets"]): + span1 = target["span1"] + span2 = target["span2"] + examples.append( + Example( + guid="%s-%s-%s" % (set_type, line_num, target_num), + text=line["text"], + span1=span1, + span2=span2, + labels=[target["label"]] if set_type != "test" else [cls.LABELS[-1]], + ) + ) + return examples diff --git a/jiant/tasks/lib/edge_probing/dep.py b/jiant/tasks/lib/edge_probing/dep.py new file mode 100644 index 000000000..7a4ba8900 --- /dev/null +++ b/jiant/tasks/lib/edge_probing/dep.py @@ -0,0 +1,124 @@ +"""Dependency labeling Edge Probing task. + +Task source paper: https://arxiv.org/pdf/1905.06316.pdf. +Task data prep directions: https://github.com/nyu-mll/jiant/blob/master/probing/data/README.md. + +""" +from dataclasses import dataclass + +from jiant.tasks.lib.templates.shared import labels_to_bimap +from jiant.tasks.lib.templates import edge_probing_two_span +from jiant.utils.python.io import read_json_lines + + +@dataclass +class Example(edge_probing_two_span.Example): + @property + def task(self): + return DepTask + + +@dataclass +class TokenizedExample(edge_probing_two_span.TokenizedExample): + pass + + +@dataclass +class DataRow(edge_probing_two_span.DataRow): + pass + + +@dataclass +class Batch(edge_probing_two_span.Batch): + pass + + +class DepTask(edge_probing_two_span.AbstractProbingTask): + Example = Example + TokenizedExample = TokenizedExample + DataRow = DataRow + Batch = Batch + + LABELS = [ + "acl", + "acl:relcl", + "advcl", + "advmod", + "amod", + "appos", + "aux", + "aux:pass", + "case", + "cc", + "cc:preconj", + "ccomp", + "compound", + "compound:prt", + "conj", + "cop", + "csubj", + "csubj:pass", + "dep", + "det", + "det:predet", + "discourse", + "dislocated", + "expl", + "fixed", + "flat", + "flat:foreign", + "goeswith", + "iobj", + "list", + "mark", + "nmod", + "nmod:npmod", + "nmod:poss", + "nmod:tmod", + "nsubj", + "nsubj:pass", + "nummod", + "obj", + "obl", + "obl:npmod", + "obl:tmod", + "orphan", + "parataxis", + "punct", + "reparandum", + "root", + "vocative", + "xcomp", + ] + LABEL_TO_ID, ID_TO_LABEL = labels_to_bimap(LABELS) + + @property + def num_spans(self): + return 2 + + def get_train_examples(self): + return self._create_examples(lines=read_json_lines(self.train_path), set_type="train") + + def get_val_examples(self): + return self._create_examples(lines=read_json_lines(self.val_path), set_type="val") + + def get_test_examples(self): + return self._create_examples(lines=read_json_lines(self.test_path), set_type="test") + + @classmethod + def _create_examples(cls, lines, set_type): + examples = [] + for (line_num, line) in enumerate(lines): + for (target_num, target) in enumerate(line["targets"]): + span1 = target["span1"] + span2 = target["span2"] + examples.append( + Example( + guid="%s-%s-%s" % (set_type, line_num, target_num), + text=line["text"], + span1=span1, + span2=span2, + labels=[target["label"]] if set_type != "test" else [cls.LABELS[-1]], + ) + ) + return examples diff --git a/jiant/tasks/lib/edge_probing/dpr.py b/jiant/tasks/lib/edge_probing/dpr.py new file mode 100644 index 000000000..4e085d30b --- /dev/null +++ b/jiant/tasks/lib/edge_probing/dpr.py @@ -0,0 +1,74 @@ +"""Definite Pronoun Resolution Edge Probing task. + +Task source paper: https://arxiv.org/pdf/1905.06316.pdf. +Task data prep directions: https://github.com/nyu-mll/jiant/blob/master/probing/data/README.md. + +""" +from dataclasses import dataclass + +from jiant.tasks.lib.templates.shared import labels_to_bimap +from jiant.tasks.lib.templates import edge_probing_two_span +from jiant.utils.python.io import read_json_lines + + +@dataclass +class Example(edge_probing_two_span.Example): + @property + def task(self): + return DprTask + + +@dataclass +class TokenizedExample(edge_probing_two_span.TokenizedExample): + pass + + +@dataclass +class DataRow(edge_probing_two_span.DataRow): + pass + + +@dataclass +class Batch(edge_probing_two_span.Batch): + pass + + +class DprTask(edge_probing_two_span.AbstractProbingTask): + Example = Example + TokenizedExample = TokenizedExample + DataRow = DataRow + Batch = Batch + + LABELS = ["entailed", "not-entailed"] + LABEL_TO_ID, ID_TO_LABEL = labels_to_bimap(LABELS) + + @property + def num_spans(self): + return 2 + + def get_train_examples(self): + return self._create_examples(lines=read_json_lines(self.train_path), set_type="train") + + def get_val_examples(self): + return self._create_examples(lines=read_json_lines(self.val_path), set_type="val") + + def get_test_examples(self): + return self._create_examples(lines=read_json_lines(self.test_path), set_type="test") + + @classmethod + def _create_examples(cls, lines, set_type): + examples = [] + for (line_num, line) in enumerate(lines): + for (target_num, target) in enumerate(line["targets"]): + span1 = target["span1"] + span2 = target["span2"] + examples.append( + Example( + guid="%s-%s-%s" % (set_type, line_num, target_num), + text=line["text"], + span1=span1, + span2=span2, + labels=[target["label"]] if set_type != "test" else [cls.LABELS[-1]], + ) + ) + return examples diff --git a/jiant/tasks/lib/edge_probing/ner.py b/jiant/tasks/lib/edge_probing/ner.py new file mode 100644 index 000000000..dd2b254f7 --- /dev/null +++ b/jiant/tasks/lib/edge_probing/ner.py @@ -0,0 +1,91 @@ +"""Named entity labeling Edge Probing task. + +Task source paper: https://arxiv.org/pdf/1905.06316.pdf. +Task data prep directions: https://github.com/nyu-mll/jiant/blob/master/probing/data/README.md. + +""" +from dataclasses import dataclass + +from jiant.tasks.lib.templates.shared import labels_to_bimap +from jiant.tasks.lib.templates import edge_probing_single_span +from jiant.utils.python.io import read_json_lines + + +@dataclass +class Example(edge_probing_single_span.Example): + @property + def task(self): + return NerTask + + +@dataclass +class TokenizedExample(edge_probing_single_span.TokenizedExample): + pass + + +@dataclass +class DataRow(edge_probing_single_span.DataRow): + pass + + +@dataclass +class Batch(edge_probing_single_span.Batch): + pass + + +class NerTask(edge_probing_single_span.AbstractProbingTask): + Example = Example + TokenizedExample = TokenizedExample + DataRow = DataRow + Batch = Batch + + LABELS = [ + "CARDINAL", + "DATE", + "EVENT", + "FAC", + "GPE", + "LANGUAGE", + "LAW", + "LOC", + "MONEY", + "NORP", + "ORDINAL", + "ORG", + "PERCENT", + "PERSON", + "PRODUCT", + "QUANTITY", + "TIME", + "WORK_OF_ART", + ] + LABEL_TO_ID, ID_TO_LABEL = labels_to_bimap(LABELS) + + @property + def num_spans(self): + return 1 + + def get_train_examples(self): + return self._create_examples(lines=read_json_lines(self.train_path), set_type="train") + + def get_val_examples(self): + return self._create_examples(lines=read_json_lines(self.val_path), set_type="val") + + def get_test_examples(self): + return self._create_examples(lines=read_json_lines(self.test_path), set_type="test") + + @classmethod + def _create_examples(cls, lines, set_type): + examples = [] + for (line_num, line) in enumerate(lines): + for (target_num, target) in enumerate(line["targets"]): + span = target["span1"] + examples.append( + Example( + guid="%s-%s-%s" % (set_type, line_num, target_num), + text=line["text"], + span=span, + labels=[target["label"]] if set_type != "test" else [cls.LABELS[-1]], + ) + ) + return examples diff --git a/jiant/tasks/lib/edge_probing/nonterminal.py b/jiant/tasks/lib/edge_probing/nonterminal.py new file mode 100644 index 000000000..b4b38e403 --- /dev/null +++ b/jiant/tasks/lib/edge_probing/nonterminal.py @@ -0,0 +1,103 @@ +"""Constituent labeling (assigning a non-terminal label) Edge Probing task. + +Task source paper: https://arxiv.org/pdf/1905.06316.pdf. +Task data prep directions: https://github.com/nyu-mll/jiant/blob/master/probing/data/README.md. + +""" +from dataclasses import dataclass + +from jiant.tasks.lib.templates.shared import labels_to_bimap +from jiant.tasks.lib.templates import edge_probing_single_span +from jiant.utils.python.io import read_json_lines + + +@dataclass +class Example(edge_probing_single_span.Example): + @property + def task(self): + return NonterminalTask + + +@dataclass +class TokenizedExample(edge_probing_single_span.TokenizedExample): + pass + + +@dataclass +class DataRow(edge_probing_single_span.DataRow): + pass + + +@dataclass +class Batch(edge_probing_single_span.Batch): + pass + + +class NonterminalTask(edge_probing_single_span.AbstractProbingTask): + Example = Example + TokenizedExample = TokenizedExample + DataRow = DataRow + Batch = Batch + + LABELS = [ + "ADJP", + "ADVP", + "CONJP", + "EMBED", + "FRAG", + "INTJ", + "LST", + "META", + "NAC", + "NML", + "NP", + "NX", + "PP", + "PRN", + "PRT", + "QP", + "RRC", + "S", + "SBAR", + "SBARQ", + "SINV", + "SQ", + "TOP", + "UCP", + "VP", + "WHADJP", + "WHADVP", + "WHNP", + "WHPP", + "X", + ] + LABEL_TO_ID, ID_TO_LABEL = labels_to_bimap(LABELS) + + @property + def num_spans(self): + return 1 + + def get_train_examples(self): + return self._create_examples(lines=read_json_lines(self.train_path), set_type="train") + + def get_val_examples(self): + return self._create_examples(lines=read_json_lines(self.val_path), set_type="val") + + def get_test_examples(self): + return self._create_examples(lines=read_json_lines(self.test_path), set_type="test") + + @classmethod + def _create_examples(cls, lines, set_type): + examples = [] + for (line_num, line) in enumerate(lines): + for (target_num, target) in enumerate(line["targets"]): + span = target["span1"] + examples.append( + Example( + guid="%s-%s-%s" % (set_type, line_num, target_num), + text=line["text"], + span=span, + labels=[target["label"]] if set_type != "test" else [cls.LABELS[-1]], + ) + ) + return examples diff --git a/jiant/tasks/lib/edge_probing/pos.py b/jiant/tasks/lib/edge_probing/pos.py new file mode 100644 index 000000000..9a80c1a5b --- /dev/null +++ b/jiant/tasks/lib/edge_probing/pos.py @@ -0,0 +1,121 @@ +"""Part-of-speech tagging Edge Probing task. + +Task source paper: https://arxiv.org/pdf/1905.06316.pdf. +Task data prep directions: https://github.com/nyu-mll/jiant/blob/master/probing/data/README.md. + +""" +from dataclasses import dataclass + +from jiant.tasks.lib.templates.shared import labels_to_bimap +from jiant.tasks.lib.templates import edge_probing_single_span +from jiant.utils.python.io import read_json_lines + + +@dataclass +class Example(edge_probing_single_span.Example): + @property + def task(self): + return PosTask + + +@dataclass +class TokenizedExample(edge_probing_single_span.TokenizedExample): + pass + + +@dataclass +class DataRow(edge_probing_single_span.DataRow): + pass + + +@dataclass +class Batch(edge_probing_single_span.Batch): + pass + + +class PosTask(edge_probing_single_span.AbstractProbingTask): + Example = Example + TokenizedExample = TokenizedExample + DataRow = DataRow + Batch = Batch + + LABELS = [ + "$", + "''", + ",", + "-LRB-", + "-RRB-", + ".", + ":", + "ADD", + "AFX", + "CC", + "CD", + "DT", + "EX", + "FW", + "HYPH", + "IN", + "JJ", + "JJR", + "JJS", + "LS", + "MD", + "NFP", + "NN", + "NNP", + "NNPS", + "NNS", + "PDT", + "POS", + "PRP", + "PRP$", + "RB", + "RBR", + "RBS", + "RP", + "SYM", + "TO", + "UH", + "VB", + "VBD", + "VBG", + "VBN", + "VBP", + "VBZ", + "WDT", + "WP", + "WP$", + "WRB", + "``", + ] + LABEL_TO_ID, ID_TO_LABEL = labels_to_bimap(LABELS) + + @property + def num_spans(self): + return 1 + + def get_train_examples(self): + return self._create_examples(lines=read_json_lines(self.train_path), set_type="train") + + def get_val_examples(self): + return self._create_examples(lines=read_json_lines(self.val_path), set_type="val") + + def get_test_examples(self): + return self._create_examples(lines=read_json_lines(self.test_path), set_type="test") + + @classmethod + def _create_examples(cls, lines, set_type): + examples = [] + for (line_num, line) in enumerate(lines): + for (target_num, target) in enumerate(line["targets"]): + span = target["span1"] + examples.append( + Example( + guid="%s-%s-%s" % (set_type, line_num, target_num), + text=line["text"], + span=span, + labels=[target["label"]] if set_type != "test" else [cls.LABELS[-1]], + ) + ) + return examples diff --git a/jiant/tasks/lib/edge_probing/semeval.py b/jiant/tasks/lib/edge_probing/semeval.py new file mode 100644 index 000000000..b016d9826 --- /dev/null +++ b/jiant/tasks/lib/edge_probing/semeval.py @@ -0,0 +1,94 @@ +"""Relation Classification Edge Probing task. + +Task source paper: https://arxiv.org/pdf/1905.06316.pdf. +Task data prep directions: https://github.com/nyu-mll/jiant/blob/master/probing/data/README.md. + +""" +from dataclasses import dataclass + +from jiant.tasks.lib.templates.shared import labels_to_bimap +from jiant.tasks.lib.templates import edge_probing_two_span +from jiant.utils.python.io import read_json_lines + + +@dataclass +class Example(edge_probing_two_span.Example): + @property + def task(self): + return SemevalTask + + +@dataclass +class TokenizedExample(edge_probing_two_span.TokenizedExample): + pass + + +@dataclass +class DataRow(edge_probing_two_span.DataRow): + pass + + +@dataclass +class Batch(edge_probing_two_span.Batch): + pass + + +class SemevalTask(edge_probing_two_span.AbstractProbingTask): + Example = Example + TokenizedExample = TokenizedExample + DataRow = DataRow + Batch = Batch + + LABELS = [ + "Cause-Effect(e1,e2)", + "Cause-Effect(e2,e1)", + "Component-Whole(e1,e2)", + "Component-Whole(e2,e1)", + "Content-Container(e1,e2)", + "Content-Container(e2,e1)", + "Entity-Destination(e1,e2)", + "Entity-Destination(e2,e1)", + "Entity-Origin(e1,e2)", + "Entity-Origin(e2,e1)", + "Instrument-Agency(e1,e2)", + "Instrument-Agency(e2,e1)", + "Member-Collection(e1,e2)", + "Member-Collection(e2,e1)", + "Message-Topic(e1,e2)", + "Message-Topic(e2,e1)", + "Other", + "Product-Producer(e1,e2)", + "Product-Producer(e2,e1)", + ] + LABEL_TO_ID, ID_TO_LABEL = labels_to_bimap(LABELS) + + @property + def num_spans(self): + return 2 + + def get_train_examples(self): + return self._create_examples(lines=read_json_lines(self.train_path), set_type="train") + + def get_val_examples(self): + return self._create_examples(lines=read_json_lines(self.val_path), set_type="val") + + def get_test_examples(self): + return self._create_examples(lines=read_json_lines(self.test_path), set_type="test") + + @classmethod + def _create_examples(cls, lines, set_type): + examples = [] + for (line_num, line) in enumerate(lines): + for (target_num, target) in enumerate(line["targets"]): + span1 = target["span1"] + span2 = target["span2"] + examples.append( + Example( + guid="%s-%s-%s" % (set_type, line_num, target_num), + text=line["text"], + span1=span1, + span2=span2, + labels=[target["label"]] if set_type != "test" else [cls.LABELS[-1]], + ) + ) + return examples diff --git a/jiant/tasks/lib/edge_probing/spr1.py b/jiant/tasks/lib/edge_probing/spr1.py new file mode 100644 index 000000000..fdc9f3d1d --- /dev/null +++ b/jiant/tasks/lib/edge_probing/spr1.py @@ -0,0 +1,95 @@ +"""Semantic proto-role (1) Edge Probing task. + +Task source paper: https://arxiv.org/pdf/1905.06316.pdf. +Task data prep directions: https://github.com/nyu-mll/jiant/blob/master/probing/data/README.md. + +""" +from dataclasses import dataclass + +from jiant.tasks.lib.templates.shared import labels_to_bimap +from jiant.tasks.lib.templates import edge_probing_two_span +from jiant.utils.python.io import read_json_lines + + +@dataclass +class Example(edge_probing_two_span.Example): + @property + def task(self): + return Spr1Task + + +@dataclass +class TokenizedExample(edge_probing_two_span.TokenizedExample): + pass + + +@dataclass +class DataRow(edge_probing_two_span.DataRow): + pass + + +@dataclass +class Batch(edge_probing_two_span.Batch): + pass + + +class Spr1Task(edge_probing_two_span.AbstractProbingTask): + Example = Example + TokenizedExample = TokenizedExample + DataRow = DataRow + Batch = Batch + + LABELS = [ + "awareness", + "change_of_location", + "change_of_state", + "changes_possession", + "created", + "destroyed", + "existed_after", + "existed_before", + "existed_during", + "exists_as_physical", + "instigation", + "location_of_event", + "makes_physical_contact", + "manipulated_by_another", + "predicate_changed_argument", + "sentient", + "stationary", + "volition", + ] + LABEL_TO_ID, ID_TO_LABEL = labels_to_bimap(LABELS) + + @property + def num_spans(self): + return 2 + + def get_train_examples(self): + return self._create_examples(lines=read_json_lines(self.train_path), set_type="train") + + def get_val_examples(self): + return self._create_examples(lines=read_json_lines(self.val_path), set_type="val") + + def get_test_examples(self): + return self._create_examples(lines=read_json_lines(self.test_path), set_type="test") + + @classmethod + def _create_examples(cls, lines, set_type): + examples = [] + for (line_num, line) in enumerate(lines): + # A line in the task's data file can contain multiple targets (span-pair + labels). + # We create an example for every target: + for (target_num, target) in enumerate(line["targets"]): + span1 = target["span1"] + span2 = target["span2"] + examples.append( + Example( + guid="%s-%s-%s" % (set_type, line_num, target_num), + text=line["text"], + span1=span1, + span2=span2, + labels=target["label"] if set_type != "test" else [cls.LABELS[-1]], + ) + ) + return examples diff --git a/jiant/tasks/lib/edge_probing/spr2.py b/jiant/tasks/lib/edge_probing/spr2.py new file mode 100644 index 000000000..07e408092 --- /dev/null +++ b/jiant/tasks/lib/edge_probing/spr2.py @@ -0,0 +1,95 @@ +"""Semantic proto-role (2) Edge Probing task. + +Task source paper: https://arxiv.org/pdf/1905.06316.pdf. +Task data prep directions: https://github.com/nyu-mll/jiant/blob/master/probing/data/README.md. + +""" +from dataclasses import dataclass + +from jiant.tasks.lib.templates.shared import labels_to_bimap +from jiant.tasks.lib.templates import edge_probing_two_span +from jiant.utils.python.io import read_json_lines + + +@dataclass +class Example(edge_probing_two_span.Example): + @property + def task(self): + return Spr2Task + + +@dataclass +class TokenizedExample(edge_probing_two_span.TokenizedExample): + pass + + +@dataclass +class DataRow(edge_probing_two_span.DataRow): + pass + + +@dataclass +class Batch(edge_probing_two_span.Batch): + pass + + +class Spr2Task(edge_probing_two_span.AbstractProbingTask): + Example = Example + TokenizedExample = TokenizedExample + DataRow = DataRow + Batch = Batch + + LABELS = [ + "awareness", + "change_of_location", + "change_of_possession", + "change_of_state", + "change_of_state_continuous", + "changes_possession", + "existed_after", + "existed_before", + "existed_during", + "exists_as_physical", + "instigation", + "location_of_event", + "makes_physical_contact", + "partitive", + "predicate_changed_argument", + "sentient", + "stationary", + "volition", + "was_for_benefit", + "was_used", + ] + LABEL_TO_ID, ID_TO_LABEL = labels_to_bimap(LABELS) + + @property + def num_spans(self): + return 2 + + def get_train_examples(self): + return self._create_examples(lines=read_json_lines(self.train_path), set_type="train") + + def get_val_examples(self): + return self._create_examples(lines=read_json_lines(self.val_path), set_type="val") + + def get_test_examples(self): + return self._create_examples(lines=read_json_lines(self.test_path), set_type="test") + + @classmethod + def _create_examples(cls, lines, set_type): + examples = [] + for (line_num, line) in enumerate(lines): + for (target_num, target) in enumerate(line["targets"]): + span1 = target["span1"] + span2 = target["span2"] + examples.append( + Example( + guid="%s-%s-%s" % (set_type, line_num, target_num), + text=line["text"], + span1=span1, + span2=span2, + labels=target["label"] if set_type != "test" else [cls.LABELS[-1]], + ) + ) + return examples diff --git a/jiant/tasks/lib/edge_probing/srl.py b/jiant/tasks/lib/edge_probing/srl.py new file mode 100644 index 000000000..8f0079cb1 --- /dev/null +++ b/jiant/tasks/lib/edge_probing/srl.py @@ -0,0 +1,141 @@ +"""Semantic role labeling Edge Probing task. + +Task source paper: https://arxiv.org/pdf/1905.06316.pdf. +Task data prep directions: https://github.com/nyu-mll/jiant/blob/master/probing/data/README.md. + +""" +from dataclasses import dataclass + +from jiant.tasks.lib.templates.shared import labels_to_bimap +from jiant.tasks.lib.templates import edge_probing_two_span +from jiant.utils.python.io import read_json_lines + + +@dataclass +class Example(edge_probing_two_span.Example): + @property + def task(self): + return SrlTask + + +@dataclass +class TokenizedExample(edge_probing_two_span.TokenizedExample): + pass + + +@dataclass +class DataRow(edge_probing_two_span.DataRow): + pass + + +@dataclass +class Batch(edge_probing_two_span.Batch): + pass + + +class SrlTask(edge_probing_two_span.AbstractProbingTask): + Example = Example + TokenizedExample = TokenizedExample + DataRow = DataRow + Batch = Batch + + LABELS = [ + "ARG0", + "ARG1", + "ARG2", + "ARG3", + "ARG4", + "ARG5", + "ARGA", + "ARGM-ADJ", + "ARGM-ADV", + "ARGM-CAU", + "ARGM-COM", + "ARGM-DIR", + "ARGM-DIS", + "ARGM-DSP", + "ARGM-EXT", + "ARGM-GOL", + "ARGM-LOC", + "ARGM-LVB", + "ARGM-MNR", + "ARGM-MOD", + "ARGM-NEG", + "ARGM-PNC", + "ARGM-PRD", + "ARGM-PRP", + "ARGM-PRR", + "ARGM-PRX", + "ARGM-REC", + "ARGM-TMP", + "C-ARG0", + "C-ARG1", + "C-ARG2", + "C-ARG3", + "C-ARG4", + "C-ARGM-ADJ", + "C-ARGM-ADV", + "C-ARGM-CAU", + "C-ARGM-COM", + "C-ARGM-DIR", + "C-ARGM-DIS", + "C-ARGM-DSP", + "C-ARGM-EXT", + "C-ARGM-LOC", + "C-ARGM-MNR", + "C-ARGM-MOD", + "C-ARGM-NEG", + "C-ARGM-PRP", + "C-ARGM-TMP", + "R-ARG0", + "R-ARG1", + "R-ARG2", + "R-ARG3", + "R-ARG4", + "R-ARG5", + "R-ARGM-ADV", + "R-ARGM-CAU", + "R-ARGM-COM", + "R-ARGM-DIR", + "R-ARGM-EXT", + "R-ARGM-GOL", + "R-ARGM-LOC", + "R-ARGM-MNR", + "R-ARGM-MOD", + "R-ARGM-PNC", + "R-ARGM-PRD", + "R-ARGM-PRP", + "R-ARGM-TMP", + ] + LABEL_TO_ID, ID_TO_LABEL = labels_to_bimap(LABELS) + + @property + def num_spans(self): + return 2 + + def get_train_examples(self): + return self._create_examples(lines=read_json_lines(self.train_path), set_type="train") + + def get_val_examples(self): + return self._create_examples(lines=read_json_lines(self.val_path), set_type="val") + + def get_test_examples(self): + return self._create_examples(lines=read_json_lines(self.test_path), set_type="test") + + @classmethod + def _create_examples(cls, lines, set_type): + examples = [] + for (line_num, line) in enumerate(lines): + for (target_num, target) in enumerate(line["targets"]): + span1 = target["span1"] + span2 = target["span2"] + examples.append( + Example( + guid="%s-%s-%s" % (set_type, line_num, target_num), + text=line["text"], + span1=span1, + span2=span2, + labels=[target["label"]] if set_type != "test" else [cls.LABELS[-1]], + ) + ) + return examples diff --git a/jiant/tasks/lib/glue_diagnostics.py b/jiant/tasks/lib/glue_diagnostics.py new file mode 100644 index 000000000..784fdc23c --- /dev/null +++ b/jiant/tasks/lib/glue_diagnostics.py @@ -0,0 +1,31 @@ +from dataclasses import dataclass + +from . import mnli + + +@dataclass +class Example(mnli.Example): + pass + + +@dataclass +class TokenizedExample(mnli.TokenizedExample): + pass + + +@dataclass +class DataRow(mnli.DataRow): + pass + + +@dataclass +class Batch(mnli.Batch): + pass + + +class GlueDiagnosticsTask(mnli.MnliTask): + def get_train_examples(self): + raise RuntimeError("This task does not support training examples") + + def get_val_examples(self): + raise RuntimeError("This task does not support validation examples") diff --git a/jiant/tasks/lib/hellaswag.py b/jiant/tasks/lib/hellaswag.py new file mode 100644 index 000000000..54112339d --- /dev/null +++ b/jiant/tasks/lib/hellaswag.py @@ -0,0 +1,61 @@ +from dataclasses import dataclass + +from jiant.tasks.lib.templates.shared import labels_to_bimap +from jiant.tasks.lib.templates import multiple_choice as mc_template +from jiant.utils.python.io import read_json_lines + + +@dataclass +class Example(mc_template.Example): + @property + def task(self): + return HellaSwagTask + + +@dataclass +class TokenizedExample(mc_template.TokenizedExample): + pass + + +@dataclass +class DataRow(mc_template.DataRow): + pass + + +@dataclass +class Batch(mc_template.Batch): + pass + + +class HellaSwagTask(mc_template.AbstractMultipleChoiceTask): + Example = Example + TokenizedExample = Example + DataRow = DataRow + Batch = Batch + + CHOICE_KEYS = [0, 1, 2, 3] + CHOICE_TO_ID, ID_TO_CHOICE = labels_to_bimap(CHOICE_KEYS) + NUM_CHOICES = len(CHOICE_KEYS) + + def get_train_examples(self): + return self._create_examples(lines=read_json_lines(self.train_path), set_type="train") + + def get_val_examples(self): + return self._create_examples(lines=read_json_lines(self.val_path), set_type="val") + + def get_test_examples(self): + return self._create_examples(lines=read_json_lines(self.test_path), set_type="test") + + @classmethod + def _create_examples(cls, lines, set_type): + examples = [] + for i, line in enumerate(lines): + examples.append( + Example( + guid="%s-%s" % (set_type, i), + prompt=line["ctx_a"], + choice_list=[line["ctx_b"] + " " + ending for ending in line["endings"]], + label=line["label"] if set_type != "test" else cls.CHOICE_KEYS[-1], + ) + ) + return examples diff --git a/jiant/tasks/lib/mlm_premasked.py b/jiant/tasks/lib/mlm_premasked.py new file mode 100644 index 000000000..4f31c5f69 --- /dev/null +++ b/jiant/tasks/lib/mlm_premasked.py @@ -0,0 +1,92 @@ +from dataclasses import dataclass +from typing import List + +import jiant.utils.python.io as py_io +from jiant.tasks.core import ( + Task, + TaskTypes, + BaseExample, +) +from jiant.tasks.utils import ExclusiveSpan +from .templates import mlm_premasked as mlm_premasked_template + + +@dataclass +class Example(BaseExample): + guid: str + text: str + # Spans over char indices + masked_spans: List[ExclusiveSpan] + + def tokenize(self, tokenizer): + # masked_tokens will be regular tokens except with tokenizer.mask_token for masked spans + # label_tokens will be tokenizer.pad_token except with the regular tokens for masked spans + masked_tokens = [] + label_tokens = [] + curr = 0 + for start, end in self.masked_spans: + # Handle text before next mask + tokenized_text = tokenizer.tokenize(self.text[curr:start]) + masked_tokens += tokenized_text + label_tokens += [tokenizer.pad_token] * len(tokenized_text) + + # Handle mask + tokenized_masked_text = tokenizer.tokenize(self.text[start:end]) + masked_tokens += [tokenizer.mask_token] * len(tokenized_masked_text) + label_tokens += tokenized_masked_text + curr = end + if curr < len(self.text): + tokenized_text = tokenizer.tokenize(self.text[curr:]) + masked_tokens += tokenized_text + label_tokens += [tokenizer.pad_token] * len(tokenized_text) + + return TokenizedExample( + guid=self.guid, masked_tokens=masked_tokens, label_tokens=label_tokens, + ) + + +@dataclass +class TokenizedExample(mlm_premasked_template.TokenizedExample): + pass + + +@dataclass +class DataRow(mlm_premasked_template.BaseDataRow): + pass + + +@dataclass +class Batch(mlm_premasked_template.Batch): + pass + + +class MLMPremaskedTask(Task): + Example = Example + TokenizedExample = TokenizedExample + DataRow = DataRow + Batch = Batch + + TASK_TYPE = TaskTypes.MASKED_LANGUAGE_MODELING + + def __init__(self, name, path_dict): + super().__init__(name=name, path_dict=path_dict) + self.mlm_probability = None + self.do_mask = False + + def get_train_examples(self): + return self._create_examples(path=self.train_path, set_type="train") + + def get_val_examples(self): + return self._create_examples(path=self.val_path, set_type="val") + + def get_test_examples(self): + return self._create_examples(path=self.test_path, set_type="test") + + @classmethod + def _create_examples(cls, path, set_type): + for i, row in enumerate(py_io.read_jsonl(path)): + yield Example( + guid="%s-%s" % (set_type, i), + text=row["text"], + masked_spans=[ExclusiveSpan(start, end) for start, end in row["masked_spans"]], + ) diff --git a/jiant/tasks/lib/mlm_pretokenized.py b/jiant/tasks/lib/mlm_pretokenized.py new file mode 100644 index 000000000..ccc72491c --- /dev/null +++ b/jiant/tasks/lib/mlm_pretokenized.py @@ -0,0 +1,92 @@ +from dataclasses import dataclass +from typing import List + +import jiant.utils.python.io as py_io +from jiant.tasks.core import ( + Task, + TaskTypes, + BaseExample, +) +from jiant.tasks.utils import ExclusiveSpan +from .templates import mlm_premasked as mlm_premasked_template + + +@dataclass +class Example(BaseExample): + guid: str + tokenized_text: List + # Spans over token indices + masked_spans: List[ExclusiveSpan] + + def tokenize(self, tokenizer): + # masked_tokens will be regular tokens except with tokenizer.mask_token for masked spans + # label_tokens will be tokenizer.pad_token except with the regular tokens for masked spans + masked_tokens = [] + label_tokens = [] + curr = 0 + for start, end in self.masked_spans: + # Handle text before next mask + tokenized_text = self.tokenized_text[curr:start] + masked_tokens += tokenized_text + label_tokens += [tokenizer.pad_token] * len(tokenized_text) + + # Handle mask + tokenized_masked_text = self.tokenized_text[start:end] + masked_tokens += [tokenizer.mask_token] * len(tokenized_masked_text) + label_tokens += tokenized_masked_text + curr = end + if curr < len(self.tokenized_text): + tokenized_text = self.tokenized_text[curr:] + masked_tokens += tokenized_text + label_tokens += [tokenizer.pad_token] * len(tokenized_text) + + return TokenizedExample( + guid=self.guid, masked_tokens=self.tokenized_text, label_tokens=label_tokens, + ) + + +@dataclass +class TokenizedExample(mlm_premasked_template.TokenizedExample): + pass + + +@dataclass +class DataRow(mlm_premasked_template.BaseDataRow): + pass + + +@dataclass +class Batch(mlm_premasked_template.Batch): + pass + + +class MLMPretokenizedTask(Task): + Example = Example + TokenizedExample = TokenizedExample + DataRow = DataRow + Batch = Batch + + TASK_TYPE = TaskTypes.MASKED_LANGUAGE_MODELING + + def __init__(self, name, path_dict): + super().__init__(name=name, path_dict=path_dict) + self.mlm_probability = None + self.do_mask = True + + def get_train_examples(self): + return self._create_examples(path=self.train_path, set_type="train") + + def get_val_examples(self): + return self._create_examples(path=self.val_path, set_type="val") + + def get_test_examples(self): + return self._create_examples(path=self.test_path, set_type="test") + + @classmethod + def _create_examples(cls, path, set_type): + for i, row in enumerate(py_io.read_jsonl(path)): + yield Example( + guid="%s-%s" % (set_type, i), + tokenized_text=row["tokenized_text"], + masked_spans=[ExclusiveSpan(start, end) for start, end in row["masked_spans"]], + ) diff --git a/jiant/tasks/lib/mlm_simple.py b/jiant/tasks/lib/mlm_simple.py new file mode 100644 index 000000000..4851e8374 --- /dev/null +++ b/jiant/tasks/lib/mlm_simple.py @@ -0,0 +1,75 @@ +from dataclasses import dataclass + +from jiant.utils.python.datastructures import ReusableGenerator +from jiant.tasks.lib.templates import mlm as mlm_template + + +@dataclass +class Example(mlm_template.Example): + pass + + +@dataclass +class TokenizedExample(mlm_template.TokenizedExample): + pass + + +@dataclass +class DataRow(mlm_template.DataRow): + pass + + +@dataclass +class Batch(mlm_template.Batch): + pass + + +@dataclass +class MaskedBatch(mlm_template.MaskedBatch): + pass + + +class MLMSimpleTask(mlm_template.MLMTask): + """Simple implementation of MLM task + - Reads from a single file per phase + - One example per line (examples that are too long will be truncated) + - Empty lines are skipped. + """ + + Example = Example + TokenizedExample = Example + DataRow = DataRow + Batch = Batch + + def __init__(self, name, path_dict, mlm_probability=0.15, do_mask=True): + super().__init__(name=name, path_dict=path_dict) + self.mlm_probability = mlm_probability + self.do_mask = do_mask + + def get_train_examples(self): + return self._create_examples(path=self.train_path, set_type="train", return_generator=True) + + def get_val_examples(self): + return self._create_examples(path=self.val_path, set_type="val", return_generator=True) + + def get_test_examples(self): + return self._create_examples(path=self.test_path, set_type="test", return_generator=True) + + @classmethod + def _get_examples_generator(cls, path, set_type): + with open(path, "r") as f: + for (i, line) in enumerate(f): + line = line.strip() + if not line: + continue + yield Example( + guid="%s-%s" % (set_type, i), text=line, + ) + + @classmethod + def _create_examples(cls, path, set_type, return_generator): + generator = ReusableGenerator(cls._get_examples_generator, path=path, set_type=set_type) + if return_generator: + return generator + else: + return list(generator) diff --git a/jiant/tasks/lib/mlqa.py b/jiant/tasks/lib/mlqa.py new file mode 100644 index 000000000..9a9ec35c5 --- /dev/null +++ b/jiant/tasks/lib/mlqa.py @@ -0,0 +1,186 @@ +import string +import re +import sys +import unicodedata +from collections import Counter + +from dataclasses import dataclass + +from jiant.tasks.lib.templates.squad_style import core as squad_style_template + + +@dataclass +class Example(squad_style_template.Example): + def tokenize(self, tokenizer): + raise NotImplementedError("SQuaD is weird") + + +@dataclass +class DataRow(squad_style_template.DataRow): + pass + + +@dataclass +class Batch(squad_style_template.Batch): + pass + + +class MlqaTask(squad_style_template.BaseSquadStyleTask): + Example = Example + DataRow = DataRow + Batch = Batch + + def __init__( + self, + name, + path_dict, + context_language, + question_language, + version_2_with_negative=False, + n_best_size=20, + max_answer_length=30, + null_score_diff_threshold=0.0, + ): + super().__init__( + name=name, + path_dict=path_dict, + version_2_with_negative=version_2_with_negative, + n_best_size=n_best_size, + max_answer_length=max_answer_length, + null_score_diff_threshold=null_score_diff_threshold, + ) + self.context_language = context_language + self.question_language = question_language + + def get_train_examples(self): + raise NotImplementedError("MLQA does not have training examples") + + @classmethod + def read_squad_examples(cls, path, set_type): + return squad_style_template.generic_read_squad_examples( + path=path, set_type=set_type, example_class=cls.Example, + ) + + +# === Evaluation === # +# MLQA has a slightly different evaluation / detokenization for different languages. +# Can de-dup this later if necessary. + +PUNCT = { + chr(i) for i in range(sys.maxunicode) if unicodedata.category(chr(i)).startswith("P") +}.union(string.punctuation) +WHITESPACE_LANGS = ["en", "es", "hi", "vi", "de", "ar"] +MIXED_SEGMENTATION_LANGS = ["zh"] + + +def whitespace_tokenize(text): + return text.split() + + +def mixed_segmentation(text): + segs_out = [] + temp_str = "" + for char in text: + if re.search(r"[\u4e00-\u9fa5]", char) or char in PUNCT: + if temp_str != "": + ss = whitespace_tokenize(temp_str) + segs_out.extend(ss) + temp_str = "" + segs_out.append(char) + else: + temp_str += char + + if temp_str != "": + ss = whitespace_tokenize(temp_str) + segs_out.extend(ss) + + return segs_out + + +def normalize_answer(s, lang): + """Lower text and remove punctuation, articles and extra whitespace.""" + + def remove_articles(text, inner_lang): + if inner_lang == "en": + return re.sub(r"\b(a|an|the)\b", " ", text) + elif inner_lang == "es": + return re.sub(r"\b(un|una|unos|unas|el|la|los|las)\b", " ", text) + elif inner_lang == "hi": + return text # Hindi does not have formal articles + elif inner_lang == "vi": + return re.sub(r"\b(của|là|cái|chiếc|những)\b", " ", text) + elif inner_lang == "de": + return re.sub( + r"\b(ein|eine|einen|einem|eines|einer|der|die|das|den|dem|des)\b", " ", text + ) + elif inner_lang == "ar": + return re.sub("\sال^|ال", " ", text) # noqa: W605 + elif inner_lang == "zh": + return text # Chinese does not have formal articles + else: + raise Exception("Unknown Language {}".format(inner_lang)) + + def white_space_fix(text, inner_lang): + if inner_lang in WHITESPACE_LANGS: + tokens = whitespace_tokenize(text) + elif inner_lang in MIXED_SEGMENTATION_LANGS: + tokens = mixed_segmentation(text) + else: + raise Exception("Unknown Language {}".format(inner_lang)) + return " ".join([t for t in tokens if t.strip() != ""]) + + def remove_punc(text): + return "".join(ch for ch in text if ch not in PUNCT) + + def lower(text): + return text.lower() + + return white_space_fix(remove_articles(remove_punc(lower(s)), lang), lang) + + +def f1_score(prediction, ground_truth, lang): + prediction_tokens = normalize_answer(prediction, lang).split() + ground_truth_tokens = normalize_answer(ground_truth, lang).split() + common = Counter(prediction_tokens) & Counter(ground_truth_tokens) + num_same = sum(common.values()) + if num_same == 0: + return 0 + precision = 1.0 * num_same / len(prediction_tokens) + recall = 1.0 * num_same / len(ground_truth_tokens) + f1 = (2 * precision * recall) / (precision + recall) + return f1 + + +def exact_match_score(prediction, ground_truth, lang): + return normalize_answer(prediction, lang) == normalize_answer(ground_truth, lang) + + +def metric_max_over_ground_truths(metric_fn, prediction, ground_truths, lang): + scores_for_ground_truths = [] + for ground_truth in ground_truths: + score = metric_fn(prediction, ground_truth, lang) + scores_for_ground_truths.append(score) + return max(scores_for_ground_truths) + + +def evaluate(dataset, predictions, lang): + f1 = exact_match = total = 0 + for article in dataset: + for paragraph in article["paragraphs"]: + for qa in paragraph["qas"]: + total += 1 + if qa["id"] not in predictions: + message = "Unanswered question " + qa["id"] + " will receive score 0." + print(message, file=sys.stderr) + continue + ground_truths = list(map(lambda x: x["text"], qa["answers"])) + prediction = predictions[qa["id"]] + exact_match += metric_max_over_ground_truths( + exact_match_score, prediction, ground_truths, lang + ) + f1 += metric_max_over_ground_truths(f1_score, prediction, ground_truths, lang) + + exact_match = 100.0 * exact_match / total + f1 = 100.0 * f1 / total + + return {"exact_match": exact_match, "f1": f1} diff --git a/jiant/tasks/lib/mnli.py b/jiant/tasks/lib/mnli.py new file mode 100644 index 000000000..6411bc234 --- /dev/null +++ b/jiant/tasks/lib/mnli.py @@ -0,0 +1,106 @@ +import numpy as np +import torch +from dataclasses import dataclass +from typing import List + +from jiant.tasks.core import ( + BaseExample, + BaseTokenizedExample, + BaseDataRow, + BatchMixin, + GlueMixin, + Task, + TaskTypes, +) +from jiant.tasks.lib.templates.shared import double_sentence_featurize, labels_to_bimap +from jiant.utils.python.io import read_jsonl + + +@dataclass +class Example(BaseExample): + guid: str + premise: str + hypothesis: str + label: str + + def tokenize(self, tokenizer): + return TokenizedExample( + guid=self.guid, + premise=tokenizer.tokenize(self.premise), + hypothesis=tokenizer.tokenize(self.hypothesis), + label_id=MnliTask.LABEL_TO_ID[self.label], + ) + + +@dataclass +class TokenizedExample(BaseTokenizedExample): + guid: str + premise: List + hypothesis: List + label_id: int + + def featurize(self, tokenizer, feat_spec): + return double_sentence_featurize( + guid=self.guid, + input_tokens_a=self.premise, + input_tokens_b=self.hypothesis, + label_id=self.label_id, + tokenizer=tokenizer, + feat_spec=feat_spec, + data_row_class=DataRow, + ) + + +@dataclass +class DataRow(BaseDataRow): + guid: str + input_ids: np.ndarray + input_mask: np.ndarray + segment_ids: np.ndarray + label_id: int + tokens: list + + +@dataclass +class Batch(BatchMixin): + input_ids: torch.LongTensor + input_mask: torch.LongTensor + segment_ids: torch.LongTensor + label_id: torch.LongTensor + tokens: list + + +class MnliTask(GlueMixin, Task): + Example = Example + TokenizedExample = Example + DataRow = DataRow + Batch = Batch + + TASK_TYPE = TaskTypes.CLASSIFICATION + LABELS = ["contradiction", "entailment", "neutral"] + LABEL_TO_ID, ID_TO_LABEL = labels_to_bimap(LABELS) + + def get_train_examples(self): + return self._create_examples(lines=read_jsonl(self.train_path), set_type="train") + + def get_val_examples(self): + return self._create_examples(lines=read_jsonl(self.val_path), set_type="val") + + def get_test_examples(self): + return self._create_examples(lines=read_jsonl(self.test_path), set_type="test") + + @classmethod + def _create_examples(cls, lines, set_type): + # noinspection DuplicatedCode + examples = [] + for (i, line) in enumerate(lines): + examples.append( + Example( + # NOTE: get_glue_preds() is dependent on this guid format. + guid="%s-%s" % (set_type, i), + premise=line["premise"], + hypothesis=line["hypothesis"], + label=line["label"] if set_type != "test" else cls.LABELS[-1], + ) + ) + return examples diff --git a/jiant/tasks/lib/mnli_mismatched.py b/jiant/tasks/lib/mnli_mismatched.py new file mode 100644 index 000000000..e3bdfa42f --- /dev/null +++ b/jiant/tasks/lib/mnli_mismatched.py @@ -0,0 +1,28 @@ +from dataclasses import dataclass + +from . import mnli + + +@dataclass +class Example(mnli.Example): + pass + + +@dataclass +class TokenizedExample(mnli.TokenizedExample): + pass + + +@dataclass +class DataRow(mnli.DataRow): + pass + + +@dataclass +class Batch(mnli.Batch): + pass + + +class MnliMismatchedTask(mnli.MnliTask): + def get_train_examples(self): + raise RuntimeError("This task does not support training examples") diff --git a/jiant/tasks/lib/mrpc.py b/jiant/tasks/lib/mrpc.py new file mode 100644 index 000000000..9cd318eaa --- /dev/null +++ b/jiant/tasks/lib/mrpc.py @@ -0,0 +1,105 @@ +import numpy as np +import torch +from dataclasses import dataclass +from typing import List + +from jiant.tasks.core import ( + BaseExample, + BaseTokenizedExample, + BaseDataRow, + BatchMixin, + GlueMixin, + Task, + TaskTypes, +) +from jiant.tasks.lib.templates.shared import double_sentence_featurize, labels_to_bimap +from jiant.utils.python.io import read_jsonl + + +@dataclass +class Example(BaseExample): + guid: str + text_a: str + text_b: str + label: str + + def tokenize(self, tokenizer): + return TokenizedExample( + guid=self.guid, + text_a=tokenizer.tokenize(self.text_a), + text_b=tokenizer.tokenize(self.text_b), + label_id=MrpcTask.LABEL_TO_ID[self.label], + ) + + +@dataclass +class TokenizedExample(BaseTokenizedExample): + guid: str + text_a: List + text_b: List + label_id: int + + def featurize(self, tokenizer, feat_spec): + return double_sentence_featurize( + guid=self.guid, + input_tokens_a=self.text_a, + input_tokens_b=self.text_b, + label_id=self.label_id, + tokenizer=tokenizer, + feat_spec=feat_spec, + data_row_class=DataRow, + ) + + +@dataclass +class DataRow(BaseDataRow): + guid: str + input_ids: np.ndarray + input_mask: np.ndarray + segment_ids: np.ndarray + label_id: int + tokens: list + + +@dataclass +class Batch(BatchMixin): + input_ids: torch.LongTensor + input_mask: torch.LongTensor + segment_ids: torch.LongTensor + label_id: torch.LongTensor + tokens: list + + +class MrpcTask(GlueMixin, Task): + Example = Example + TokenizedExample = Example + DataRow = DataRow + Batch = Batch + + TASK_TYPE = TaskTypes.CLASSIFICATION + LABELS = ["0", "1"] + LABEL_TO_ID, ID_TO_LABEL = labels_to_bimap(LABELS) + + def get_train_examples(self): + return self._create_examples(lines=read_jsonl(self.train_path), set_type="train") + + def get_val_examples(self): + return self._create_examples(lines=read_jsonl(self.val_path), set_type="val") + + def get_test_examples(self): + return self._create_examples(lines=read_jsonl(self.test_path), set_type="test") + + @classmethod + def _create_examples(cls, lines, set_type): + examples = [] + for (i, line) in enumerate(lines): + examples.append( + Example( + # NOTE: get_glue_preds() is dependent on this guid format. + guid="%s-%s" % (set_type, i), + text_a=line["text_a"], + text_b=line["text_b"], + label=line["label"] if set_type != "test" else cls.LABELS[-1], + ) + ) + return examples diff --git a/jiant/tasks/lib/multirc.py b/jiant/tasks/lib/multirc.py new file mode 100644 index 000000000..658b85d9e --- /dev/null +++ b/jiant/tasks/lib/multirc.py @@ -0,0 +1,199 @@ +import collections +import numpy as np + +import torch +from dataclasses import dataclass +from typing import List + +from jiant.tasks.core import ( + BaseExample, + BaseTokenizedExample, + BaseDataRow, + BatchMixin, + SuperGlueMixin, + Task, + TaskTypes, +) +from jiant.tasks.lib.templates.shared import ( + labels_to_bimap, + add_cls_token, + create_input_set_from_tokens_and_segments, +) +from jiant.tasks.utils import truncate_sequences +from jiant.utils.python.io import read_json_lines + + +@dataclass +class Example(BaseExample): + guid: str + paragraph: str + question: str + answer: str + label: str + question_id: int + + def tokenize(self, tokenizer): + return TokenizedExample( + guid=self.guid, + paragraph=tokenizer.tokenize(self.paragraph), + question=tokenizer.tokenize(self.question), + answer=tokenizer.tokenize(self.answer), + label_id=MultiRCTask.LABEL_TO_ID[self.label], + question_id=self.question_id, + ) + + +@dataclass +class TokenizedExample(BaseTokenizedExample): + guid: str + paragraph: List + question: List + answer: List + label_id: int + question_id: int + + def featurize(self, tokenizer, feat_spec): + + if feat_spec.sep_token_extra: + maybe_extra_sep = [tokenizer.sep_token] + maybe_extra_sep_segment_id = [feat_spec.sequence_a_segment_id] + special_tokens_count = 4 + else: + maybe_extra_sep = [] + maybe_extra_sep_segment_id = [] + special_tokens_count = 3 + + paragraph = truncate_sequences( + tokens_ls=[self.paragraph], + max_length=( + feat_spec.max_seq_length + - special_tokens_count + - len(self.question) + - len(self.answer) + ), + )[0] + unpadded_inputs = add_cls_token( + unpadded_tokens=( + paragraph + + self.question + + [tokenizer.sep_token] + + maybe_extra_sep + + self.answer + + [tokenizer.sep_token] + ), + unpadded_segment_ids=( + [feat_spec.sequence_a_segment_id] * len(paragraph) + + [feat_spec.sequence_a_segment_id] * (len(self.question) + 1) + + maybe_extra_sep_segment_id + + [feat_spec.sequence_b_segment_id] * (len(self.answer) + 1) + ), + tokenizer=tokenizer, + feat_spec=feat_spec, + ) + input_set = create_input_set_from_tokens_and_segments( + unpadded_tokens=unpadded_inputs.unpadded_tokens, + unpadded_segment_ids=unpadded_inputs.unpadded_segment_ids, + tokenizer=tokenizer, + feat_spec=feat_spec, + ) + return DataRow( + guid=self.guid, + input_ids=np.array(input_set.input_ids), + input_mask=np.array(input_set.input_mask), + segment_ids=np.array(input_set.segment_ids), + label_id=self.label_id, + tokens=unpadded_inputs.unpadded_tokens, + question_id=self.question_id, + ) + + +@dataclass +class DataRow(BaseDataRow): + guid: str + input_ids: np.ndarray + input_mask: np.ndarray + segment_ids: np.ndarray + label_id: int + tokens: list + question_id: int + + +@dataclass +class Batch(BatchMixin): + input_ids: torch.LongTensor + input_mask: torch.LongTensor + segment_ids: torch.LongTensor + label_id: torch.LongTensor + tokens: list + + +class MultiRCTask(SuperGlueMixin, Task): + Example = Example + TokenizedExample = Example + DataRow = DataRow + Batch = Batch + + TASK_TYPE = TaskTypes.CLASSIFICATION + LABELS = [0, 1] + LABEL_TO_ID, ID_TO_LABEL = labels_to_bimap(LABELS) + + def __init__(self, name, path_dict): + super().__init__(name=name, path_dict=path_dict) + self.name = name + self.path_dict = path_dict + + def get_train_examples(self): + return self._create_examples(lines=read_json_lines(self.train_path), set_type="train") + + def get_val_examples(self): + return self._create_examples(lines=read_json_lines(self.val_path), set_type="val") + + def get_test_examples(self): + return self._create_examples(lines=read_json_lines(self.test_path), set_type="test") + + def _create_examples(self, lines, set_type): + examples = [] + for line in lines: + passage = line["passage"]["text"] + passage_id = line["idx"] + for question_dict in line["passage"]["questions"]: + question = question_dict["question"] + question_id = question_dict["idx"] + for answer_dict in question_dict["answers"]: + answer_id = answer_dict["idx"] + answer = answer_dict["text"] + examples.append( + Example( + # NOTE: MultiRCTask.super_glue_format_preds() is + # dependent on this guid format. + guid="%s-%s-%s-%s" % (set_type, passage_id, question_id, answer_id), + paragraph=passage, + question=question, + answer=answer, + label=answer_dict["label"] if set_type != "test" else self.LABELS[-1], + question_id=question_id, + ) + ) + return examples + + @staticmethod + def super_glue_format_preds(pred_dict): + """Reformat this task's raw predictions to have the structure expected + by SuperGLUE. + """ + lines = [] + # formatting code adapted from: https://github.com/nyu-mll/jiant/blob/ + # 14fae87d2ebc5a45dbe7254e9007d1a148dd6b18/jiant/evaluate.py#L427 + par_qst_ans_d = collections.defaultdict(lambda: collections.defaultdict(list)) + for pred, guid in zip(list(pred_dict["preds"]), list(pred_dict["guids"])): + passage_id, question_id, answer_id = [int(i) for i in guid.split("-")[1:]] + ans_d = {"idx": answer_id, "label": int(pred)} + par_qst_ans_d[passage_id][question_id].append(ans_d) + for par_idx, qst_ans_d in par_qst_ans_d.items(): + qst_ds = [] + for qst_idx, answers in qst_ans_d.items(): + qst_d = {"idx": qst_idx, "answers": answers} + qst_ds.append(qst_d) + out_d = {"idx": par_idx, "passage": {"questions": qst_ds}} + lines.append(out_d) + return lines diff --git a/jiant/tasks/lib/panx.py b/jiant/tasks/lib/panx.py new file mode 100644 index 000000000..0c1ea18a0 --- /dev/null +++ b/jiant/tasks/lib/panx.py @@ -0,0 +1,190 @@ +import numpy as np +import torch +from dataclasses import dataclass +from typing import List, Union + +from jiant.tasks.core import ( + BaseExample, + BaseTokenizedExample, + BaseDataRow, + BatchMixin, + Task, + TaskTypes, +) +from jiant.tasks.lib.templates.shared import ( + labels_to_bimap, + create_input_set_from_tokens_and_segments, + construct_single_input_tokens_and_segment_ids, + pad_single_with_feat_spec, +) +from jiant.utils.python.datastructures import zip_equal +from jiant.utils.python.io import read_file_lines + +ARBITRARY_OVERLY_LONG_WORD_CONSTRAINT = 100 +# In a rare number of cases, a single word (usually something like a mis-processed URL) +# is overly long, and should not be treated as a real multi-subword-token word. +# In these cases, we simply replace it with an UNK token. + + +@dataclass +class Example(BaseExample): + guid: str + tokens: List[str] + pos_list: List[str] + + def tokenize(self, tokenizer): + all_tokenized_tokens = [] + labels = [] + label_mask = [] + for token, pos in zip_equal(self.tokens, self.pos_list): + # Tokenize each "token" separately, assign label only to first token + tokenized = tokenizer.tokenize(token) + # If the token can't be tokenized, or is too long, replace with a single + if len(tokenized) == 0 or len(tokenized) > ARBITRARY_OVERLY_LONG_WORD_CONSTRAINT: + tokenized = [tokenizer.unk_token] + all_tokenized_tokens += tokenized + padding_length = len(tokenized) - 1 + labels += [PanxTask.LABEL_TO_ID.get(pos, None)] + [None] * padding_length + label_mask += [1] + [0] * padding_length + + return TokenizedExample( + guid=self.guid, tokens=all_tokenized_tokens, labels=labels, label_mask=label_mask, + ) + + +@dataclass +class TokenizedExample(BaseTokenizedExample): + guid: str + tokens: List + labels: List[Union[int, None]] + label_mask: List[int] + + def featurize(self, tokenizer, feat_spec): + unpadded_inputs = construct_single_input_tokens_and_segment_ids( + input_tokens=self.tokens, tokenizer=tokenizer, feat_spec=feat_spec, + ) + input_set = create_input_set_from_tokens_and_segments( + unpadded_tokens=unpadded_inputs.unpadded_tokens, + unpadded_segment_ids=unpadded_inputs.unpadded_segment_ids, + tokenizer=tokenizer, + feat_spec=feat_spec, + ) + + # Replicate padding / additional tokens for the label ids and mask + if feat_spec.sep_token_extra: + label_suffix = [None, None] + mask_suffix = [0, 0] + special_tokens_count = 3 # CLS, SEP-SEP + else: + label_suffix = [None] + mask_suffix = [0] + special_tokens_count = 2 # CLS, SEP + unpadded_labels = ( + [None] + self.labels[: feat_spec.max_seq_length - special_tokens_count] + label_suffix + ) + unpadded_labels = [i if i is not None else -1 for i in unpadded_labels] + unpadded_label_mask = ( + [0] + self.label_mask[: feat_spec.max_seq_length - special_tokens_count] + mask_suffix + ) + + padded_labels = pad_single_with_feat_spec( + ls=unpadded_labels, feat_spec=feat_spec, pad_idx=-1, + ) + padded_label_mask = pad_single_with_feat_spec( + ls=unpadded_label_mask, feat_spec=feat_spec, pad_idx=0, + ) + + return DataRow( + guid=self.guid, + input_ids=np.array(input_set.input_ids), + input_mask=np.array(input_set.input_mask), + segment_ids=np.array(input_set.segment_ids), + label_ids=np.array(padded_labels), + label_mask=np.array(padded_label_mask), + tokens=unpadded_inputs.unpadded_tokens, + ) + + +@dataclass +class DataRow(BaseDataRow): + guid: str + input_ids: np.ndarray + input_mask: np.ndarray + segment_ids: np.ndarray + label_ids: np.ndarray + label_mask: np.ndarray + tokens: list + + +@dataclass +class Batch(BatchMixin): + input_ids: torch.LongTensor + input_mask: torch.LongTensor + segment_ids: torch.LongTensor + label_ids: torch.LongTensor + label_mask: torch.LongTensor + tokens: list + + +class PanxTask(Task): + + Example = Example + TokenizedExample = Example + DataRow = DataRow + Batch = Batch + + TASK_TYPE = TaskTypes.TAGGING + LABELS = ["B-LOC", "B-ORG", "B-PER", "I-LOC", "I-ORG", "I-PER", "O"] + LABEL_TO_ID, ID_TO_LABEL = labels_to_bimap(LABELS) + + def __init__(self, name, path_dict, language): + super().__init__(name=name, path_dict=path_dict) + self.language = language + + @property + def num_labels(self): + return len(self.LABELS) + + def get_train_examples(self): + return self._create_examples(data_path=self.path_dict["train"], set_type="train") + + def get_val_examples(self): + return self._create_examples(data_path=self.path_dict["val"], set_type="val") + + def get_test_examples(self): + return self._create_examples(data_path=self.path_dict["test"], set_type="test") + + @classmethod + def _create_examples(cls, data_path, set_type): + curr_token_list, curr_pos_list = [], [] + data_lines = read_file_lines(data_path, "r", encoding="utf-8") + examples = [] + idx = 0 + for data_line in data_lines: + data_line = data_line.strip() + if data_line: + if set_type == "test": + line_tokens = data_line.split("\t") + if len(line_tokens) == 2: + token, pos = line_tokens + else: + token, pos = data_line, None + else: + token, pos = data_line.split("\t") + curr_token_list.append(token) + curr_pos_list.append(pos) + else: + examples.append( + Example( + guid="%s-%s" % (set_type, idx), + tokens=curr_token_list, + pos_list=curr_pos_list, + ) + ) + idx += 1 + curr_token_list, curr_pos_list = [], [] + if curr_token_list: + examples.append( + Example(guid="%s-%s" % (idx, idx), tokens=curr_token_list, pos_list=curr_pos_list) + ) + return examples diff --git a/jiant/tasks/lib/pawsx.py b/jiant/tasks/lib/pawsx.py new file mode 100644 index 000000000..9ec0caa88 --- /dev/null +++ b/jiant/tasks/lib/pawsx.py @@ -0,0 +1,107 @@ +import numpy as np +import torch +from dataclasses import dataclass +from typing import List + +from jiant.tasks.core import ( + BaseExample, + BaseTokenizedExample, + BaseDataRow, + BatchMixin, + Task, + TaskTypes, +) +from jiant.tasks.lib.templates.shared import double_sentence_featurize, labels_to_bimap +from jiant.utils.python.io import read_file_lines + + +@dataclass +class Example(BaseExample): + guid: str + text_a: str + text_b: str + label: str + + def tokenize(self, tokenizer): + return TokenizedExample( + guid=self.guid, + text_a=tokenizer.tokenize(self.text_a), + text_b=tokenizer.tokenize(self.text_b), + label_id=PawsXTask.LABEL_TO_ID[self.label], + ) + + +@dataclass +class TokenizedExample(BaseTokenizedExample): + guid: str + text_a: List + text_b: List + label_id: int + + def featurize(self, tokenizer, feat_spec): + return double_sentence_featurize( + guid=self.guid, + input_tokens_a=self.text_a, + input_tokens_b=self.text_b, + label_id=self.label_id, + tokenizer=tokenizer, + feat_spec=feat_spec, + data_row_class=DataRow, + ) + + +@dataclass +class DataRow(BaseDataRow): + guid: str + input_ids: np.ndarray + input_mask: np.ndarray + segment_ids: np.ndarray + label_id: int + tokens: list + + +@dataclass +class Batch(BatchMixin): + input_ids: torch.LongTensor + input_mask: torch.LongTensor + segment_ids: torch.LongTensor + label_id: torch.LongTensor + tokens: list + + +class PawsXTask(Task): + Example = Example + TokenizedExample = Example + DataRow = DataRow + Batch = Batch + + TASK_TYPE = TaskTypes.CLASSIFICATION + LABELS = ["0", "1"] + LABEL_TO_ID, ID_TO_LABEL = labels_to_bimap(LABELS) + + def __init__(self, name, path_dict, language): + super().__init__(name=name, path_dict=path_dict) + self.language = language + + def get_train_examples(self): + return self._create_examples(lines=read_file_lines(self.train_path), set_type="train") + + def get_val_examples(self): + return self._create_examples(lines=read_file_lines(self.val_path), set_type="val") + + def get_test_examples(self): + return self._create_examples(lines=read_file_lines(self.test_path), set_type="test") + + @classmethod + def _create_examples(cls, lines, set_type): + examples = [] + for (i, line) in enumerate(lines): + # Skip the header (first line) + if i == 0: + continue + segments = line.strip().split("\t") + idx, text_a, text_b, label = segments + examples.append( + Example(guid="%s-%s" % (set_type, idx), text_a=text_a, text_b=text_b, label=label) + ) + return examples diff --git a/jiant/tasks/lib/qamr.py b/jiant/tasks/lib/qamr.py new file mode 100644 index 000000000..30f2166bd --- /dev/null +++ b/jiant/tasks/lib/qamr.py @@ -0,0 +1,69 @@ +import pandas as pd +import nltk + +from jiant.tasks.lib.templates import span_prediction as span_pred_template +from jiant.utils.retokenize import TokenAligner + + +class QAMRTask(span_pred_template.AbstractSpanPredictionTask): + def get_train_examples(self): + return self._create_examples(self.train_path, set_type="train") + + def get_val_examples(self): + return self._create_examples(self.val_path, set_type="val") + + def get_test_examples(self): + return self._create_examples(self.test_path, set_type="test") + + def _create_examples(self, qa_file_path, set_type): + wiki_df = pd.read_csv(self.path_dict["wiki_dict"], sep="\t", names=["sent_id", "text"]) + wiki_dict = {row.sent_id: row.text for row in wiki_df.itertuples(index=False)} + + data_df = pd.read_csv( + qa_file_path, + sep="\t", + header=None, + names=[ + "sent_id", + "target_ids", + "worker_id", + "qa_index", + "qa_word", + "question", + "answer", + "response1", + "response2", + ], + ) + data_df["sent"] = data_df["sent_id"].apply(wiki_dict.get) + + examples = [] + ptb_detokenizer = nltk.tokenize.treebank.TreebankWordDetokenizer() + for i, row in enumerate(data_df.itertuples(index=False)): + # Answer indices are a space-limited list of numbers. + # We simply take the min/max of the indices + answer_idxs = list(map(int, row.answer.split())) + answer_token_start, answer_token_end = min(answer_idxs), max(answer_idxs) + passage_ptb_tokens = row.sent.split() + passage_space_tokens = ptb_detokenizer.detokenize( + passage_ptb_tokens, convert_parentheses=True + ).split() + passage_space_str = " ".join(passage_space_tokens) + + token_aligner = TokenAligner(source=passage_ptb_tokens, target=passage_space_tokens) + answer_char_span = token_aligner.project_token_to_char_span( + answer_token_start, answer_token_end, inclusive=True + ) + answer_str = passage_space_str[answer_char_span[0] : answer_char_span[1] + 1] + + examples.append( + span_pred_template.Example( + guid="%s-%s" % (set_type, i), + passage=passage_space_str, + question=row.question, + answer=answer_str, + answer_char_span=answer_char_span, + ) + ) + + return examples diff --git a/jiant/tasks/lib/qasrl.py b/jiant/tasks/lib/qasrl.py new file mode 100644 index 000000000..422da8414 --- /dev/null +++ b/jiant/tasks/lib/qasrl.py @@ -0,0 +1,86 @@ +import gzip +import nltk +import json + +from jiant.tasks.lib.templates import span_prediction as span_pred_template +from jiant.utils.retokenize import TokenAligner + + +class QASRLTask(span_pred_template.AbstractSpanPredictionTask): + def get_train_examples(self): + return self._create_examples(self.train_path, set_type="train") + + def get_val_examples(self): + return self._create_examples(self.val_path, set_type="val") + + def get_test_examples(self): + return self._create_examples(self.test_path, set_type="test") + + def _create_examples(self, file_path, set_type): + + with gzip.open(file_path) as f: + lines = f.read().splitlines() + + examples = [] + ptb_detokenizer = nltk.tokenize.treebank.TreebankWordDetokenizer() + + for line in lines: + datum = json.loads(line) + datum = { + "sentence_tokens": datum["sentenceTokens"], + "entries": [ + { + "verb": verb_entry["verbInflectedForms"]["stem"], + "verb_idx": verb_idx, + "questions": { + question: [ + [ + { + "tokens": datum["sentenceTokens"][span[0] : span[1]], + "span": (span[0], span[1] - 1), + } + for span in answer_judgment["spans"] + ] + for answer_judgment in q_data["answerJudgments"] + if answer_judgment["isValid"] + ] + for question, q_data in verb_entry["questionLabels"].items() + }, + } + for verb_idx, verb_entry in datum["verbEntries"].items() + ], + } + + passage_ptb_tokens = datum["sentence_tokens"] + passage_space_tokens = ptb_detokenizer.detokenize( + passage_ptb_tokens, convert_parentheses=True + ).split() + passage_space_str = " ".join(passage_space_tokens) + + token_aligner = TokenAligner(source=passage_ptb_tokens, target=passage_space_tokens) + + for entry in datum["entries"]: + for question, answer_list in entry["questions"].items(): + for answer in answer_list: + for answer_span in answer: + try: + answer_char_span = token_aligner.project_token_to_char_span( + answer_span["span"][0], answer_span["span"][1], inclusive=True + ) + except ValueError: + continue + answer_str = passage_space_str[ + answer_char_span[0] : answer_char_span[1] + 1 + ] + + examples.append( + span_pred_template.Example( + guid="%s-%s" % (set_type, len(examples)), + passage=passage_space_str, + question=question, + answer=answer_str, + answer_char_span=answer_char_span, + ) + ) + + return examples diff --git a/jiant/tasks/lib/qnli.py b/jiant/tasks/lib/qnli.py new file mode 100644 index 000000000..844919b18 --- /dev/null +++ b/jiant/tasks/lib/qnli.py @@ -0,0 +1,104 @@ +import numpy as np +import torch +from dataclasses import dataclass +from typing import List + +from jiant.tasks.core import ( + BaseExample, + BaseTokenizedExample, + BaseDataRow, + BatchMixin, + GlueMixin, + Task, + TaskTypes, +) +from jiant.tasks.lib.templates.shared import double_sentence_featurize, labels_to_bimap +from jiant.utils.python.io import read_jsonl + + +@dataclass +class Example(BaseExample): + guid: str + input_premise: str + input_hypothesis: str + label: str + + def tokenize(self, tokenizer): + return TokenizedExample( + guid=self.guid, + input_premise=tokenizer.tokenize(self.input_premise), + input_hypothesis=tokenizer.tokenize(self.input_hypothesis), + label_id=QnliTask.LABEL_TO_ID[self.label], + ) + + +@dataclass +class TokenizedExample(BaseTokenizedExample): + guid: str + input_premise: List + input_hypothesis: List + label_id: int + + def featurize(self, tokenizer, feat_spec): + return double_sentence_featurize( + guid=self.guid, + input_tokens_a=self.input_premise, + input_tokens_b=self.input_hypothesis, + label_id=self.label_id, + tokenizer=tokenizer, + feat_spec=feat_spec, + data_row_class=DataRow, + ) + + +@dataclass +class DataRow(BaseDataRow): + guid: str + input_ids: np.ndarray + input_mask: np.ndarray + segment_ids: np.ndarray + label_id: int + tokens: list + + +@dataclass +class Batch(BatchMixin): + input_ids: torch.LongTensor + input_mask: torch.LongTensor + segment_ids: torch.LongTensor + label_id: torch.LongTensor + tokens: list + + +class QnliTask(GlueMixin, Task): + Example = Example + TokenizedExample = Example + DataRow = DataRow + Batch = Batch + + TASK_TYPE = TaskTypes.CLASSIFICATION + LABELS = ["entailment", "not_entailment"] + LABEL_TO_ID, ID_TO_LABEL = labels_to_bimap(LABELS) + + def get_train_examples(self): + return self._create_examples(lines=read_jsonl(self.train_path), set_type="train") + + def get_val_examples(self): + return self._create_examples(lines=read_jsonl(self.val_path), set_type="val") + + def get_test_examples(self): + return self._create_examples(lines=read_jsonl(self.test_path), set_type="test") + + @classmethod + def _create_examples(cls, lines, set_type): + examples = [] + for (i, line) in enumerate(lines): + examples.append( + Example( + guid="%s-%s" % (set_type, i), + input_premise=line["premise"], + input_hypothesis=line["hypothesis"], + label=line["label"] if set_type != "test" else cls.LABELS[-1], + ) + ) + return examples diff --git a/jiant/tasks/lib/qqp.py b/jiant/tasks/lib/qqp.py new file mode 100644 index 000000000..e289c9162 --- /dev/null +++ b/jiant/tasks/lib/qqp.py @@ -0,0 +1,104 @@ +import numpy as np +import torch +from dataclasses import dataclass +from typing import List + +from jiant.tasks.core import ( + BaseExample, + BaseTokenizedExample, + BaseDataRow, + BatchMixin, + GlueMixin, + Task, + TaskTypes, +) +from jiant.tasks.lib.templates.shared import double_sentence_featurize, labels_to_bimap +from jiant.utils.python.io import read_jsonl + + +@dataclass +class Example(BaseExample): + guid: str + text_a: str + text_b: str + label: str + + def tokenize(self, tokenizer): + return TokenizedExample( + guid=self.guid, + text_a=tokenizer.tokenize(self.text_a), + text_b=tokenizer.tokenize(self.text_b), + label_id=QqpTask.LABEL_TO_ID[self.label], + ) + + +@dataclass +class TokenizedExample(BaseTokenizedExample): + guid: str + text_a: List + text_b: List + label_id: int + + def featurize(self, tokenizer, feat_spec): + return double_sentence_featurize( + guid=self.guid, + input_tokens_a=self.text_a, + input_tokens_b=self.text_b, + label_id=self.label_id, + tokenizer=tokenizer, + feat_spec=feat_spec, + data_row_class=DataRow, + ) + + +@dataclass +class DataRow(BaseDataRow): + guid: str + input_ids: np.ndarray + input_mask: np.ndarray + segment_ids: np.ndarray + label_id: int + tokens: list + + +@dataclass +class Batch(BatchMixin): + input_ids: torch.LongTensor + input_mask: torch.LongTensor + segment_ids: torch.LongTensor + label_id: torch.LongTensor + tokens: list + + +class QqpTask(GlueMixin, Task): + Example = Example + TokenizedExample = Example + DataRow = DataRow + Batch = Batch + + TASK_TYPE = TaskTypes.CLASSIFICATION + LABELS = ["0", "1"] + LABEL_TO_ID, ID_TO_LABEL = labels_to_bimap(LABELS) + + def get_train_examples(self): + return self._create_examples(lines=read_jsonl(self.train_path), set_type="train") + + def get_val_examples(self): + return self._create_examples(lines=read_jsonl(self.val_path), set_type="val") + + def get_test_examples(self): + return self._create_examples(lines=read_jsonl(self.test_path), set_type="test") + + @classmethod + def _create_examples(cls, lines, set_type): + examples = [] + for (i, line) in enumerate(lines): + examples.append( + Example( + guid="%s-%s" % (set_type, i), + text_a=line["text_a"], + text_b=line["text_b"], + label=line["label"] if set_type != "test" else cls.LABELS[-1], + ) + ) + return examples diff --git a/jiant/tasks/lib/record.py b/jiant/tasks/lib/record.py new file mode 100644 index 000000000..9aff6722a --- /dev/null +++ b/jiant/tasks/lib/record.py @@ -0,0 +1,173 @@ +import numpy as np +import torch +from dataclasses import dataclass +from typing import List + +from jiant.tasks.core import ( + BaseExample, + BaseTokenizedExample, + BaseDataRow, + BatchMixin, + SuperGlueMixin, + Task, + TaskTypes, +) +from jiant.tasks.lib.templates.shared import labels_to_bimap, double_sentence_featurize +from jiant.utils.python.io import read_json_lines + + +@dataclass +class Example(BaseExample): + guid: str + passage_text: str + query_text: str + entity_start_char_idx: int # unused + entity_end_char_idx: int # unused + entity_str: str + passage_idx: int + question_idx: int + answers_dict: dict + label: bool + + def tokenize(self, tokenizer): + filled_query_text = self.query_text.replace("@placeholder", self.entity_str) + return TokenizedExample( + guid=self.guid, + passage_tokens=tokenizer.tokenize(self.passage_text), + query_tokens=tokenizer.tokenize(filled_query_text), + label_id=ReCoRDTask.LABEL_TO_ID[self.label], + entity_str=self.entity_str, + label_set=set(self.answers_dict.values()), + ) + + +@dataclass +class TokenizedExample(BaseTokenizedExample): + guid: str + passage_tokens: List + query_tokens: List + label_id: int + entity_str: str + label_set: set + + def featurize(self, tokenizer, feat_spec): + data_row = double_sentence_featurize( + guid=self.guid, + input_tokens_a=self.passage_tokens, + input_tokens_b=self.query_tokens, + label_id=self.label_id, + tokenizer=tokenizer, + feat_spec=feat_spec, + data_row_class=DataRow, + ) + data_row.entity_str = self.entity_str + data_row.label_set = self.label_set + return data_row + + +@dataclass +class DataRow(BaseDataRow): + guid: str + input_ids: np.ndarray + input_mask: np.ndarray + segment_ids: np.ndarray + label_id: int + tokens: list + entity_str: str + label_set: set + + def __init__( + self, + guid, + input_ids, + input_mask, + segment_ids, + label_id, + tokens, + entity_str=None, + label_set=None, + ): + self.guid = guid + self.input_ids = input_ids + self.input_mask = input_mask + self.segment_ids = segment_ids + self.label_id = label_id + self.tokens = tokens + self.entity_str = entity_str + self.label_set = label_set + + +@dataclass +class Batch(BatchMixin): + input_ids: torch.LongTensor + input_mask: torch.LongTensor + segment_ids: torch.LongTensor + label_id: torch.LongTensor + tokens: list + entity_str: str + label_set: set + + +class ReCoRDTask(SuperGlueMixin, Task): + Example = Example + TokenizedExample = Example + DataRow = DataRow + Batch = Batch + + TASK_TYPE = TaskTypes.CLASSIFICATION + LABELS = [False, True] + LABEL_TO_ID, ID_TO_LABEL = labels_to_bimap(LABELS) + + def get_train_examples(self): + return self._create_examples(lines=read_json_lines(self.train_path), set_type="train") + + def get_val_examples(self): + return self._create_examples(lines=read_json_lines(self.val_path), set_type="val") + + def get_test_examples(self): + return self._create_examples(lines=read_json_lines(self.test_path), set_type="test") + + @classmethod + def _create_examples(cls, lines, set_type): + examples = [] + for line in lines: + passage_text = line["passage"]["text"] + for qas in line["qas"]: + answers_dict = {} + if set_type != "test": + answers_dict = { + (answer["start"], answer["end"]): answer["text"] + for answer in qas["answers"] + } + for entity in line["passage"]["entities"]: + label = False + entity_span = (entity["start"], entity["end"]) + if set_type != "test": + if entity_span in answers_dict: + assert ( + passage_text[entity_span[0] : entity_span[1] + 1] + == answers_dict[entity_span] + ) + label = True + + examples.append( + Example( + # NOTE: ReCoRDTask.super_glue_format_preds() is + # dependent on this guid format. + guid="%s-%s-%s" % (set_type, len(examples), qas["idx"]), + passage_text=passage_text, + query_text=qas["query"], + entity_start_char_idx=entity_span[0], + entity_end_char_idx=entity_span[1] + 1, # make exclusive + entity_str=passage_text[entity_span[0] : entity_span[1] + 1], + passage_idx=line["idx"], + question_idx=qas["idx"], + answers_dict=answers_dict, + label=label, + ) + ) + return examples + + @staticmethod + def super_glue_format_preds(pred_dict): + return pred_dict["preds"] diff --git a/jiant/tasks/lib/rte.py b/jiant/tasks/lib/rte.py new file mode 100644 index 000000000..923c546dc --- /dev/null +++ b/jiant/tasks/lib/rte.py @@ -0,0 +1,114 @@ +import numpy as np +import torch +from dataclasses import dataclass +from typing import List + +from jiant.tasks.core import ( + BaseExample, + BaseTokenizedExample, + BaseDataRow, + BatchMixin, + GlueMixin, + SuperGlueMixin, + Task, + TaskTypes, +) +from jiant.tasks.lib.templates.shared import double_sentence_featurize, labels_to_bimap +from jiant.utils.python.io import read_jsonl + + +@dataclass +class Example(BaseExample): + guid: str + input_premise: str + input_hypothesis: str + label: str + + def tokenize(self, tokenizer): + return TokenizedExample( + guid=self.guid, + input_premise=tokenizer.tokenize(self.input_premise), + input_hypothesis=tokenizer.tokenize(self.input_hypothesis), + label_id=RteTask.LABEL_TO_ID[self.label], + ) + + +@dataclass +class TokenizedExample(BaseTokenizedExample): + guid: str + input_premise: List + input_hypothesis: List + label_id: int + + def featurize(self, tokenizer, feat_spec): + return double_sentence_featurize( + guid=self.guid, + input_tokens_a=self.input_premise, + input_tokens_b=self.input_hypothesis, + label_id=self.label_id, + tokenizer=tokenizer, + feat_spec=feat_spec, + data_row_class=DataRow, + ) + + +@dataclass +class DataRow(BaseDataRow): + guid: str + input_ids: np.ndarray + input_mask: np.ndarray + segment_ids: np.ndarray + label_id: int + tokens: list + + +@dataclass +class Batch(BatchMixin): + input_ids: torch.LongTensor + input_mask: torch.LongTensor + segment_ids: torch.LongTensor + label_id: torch.LongTensor + tokens: list + + +class RteTask(SuperGlueMixin, GlueMixin, Task): + Example = Example + TokenizedExample = Example + DataRow = DataRow + Batch = Batch + + TASK_TYPE = TaskTypes.CLASSIFICATION + LABELS = ["entailment", "not_entailment"] + LABEL_TO_ID, ID_TO_LABEL = labels_to_bimap(LABELS) + + def get_train_examples(self): + return self._create_examples(lines=read_jsonl(self.train_path), set_type="train") + + def get_val_examples(self): + return self._create_examples(lines=read_jsonl(self.val_path), set_type="val") + + def get_test_examples(self): + return self._create_examples(lines=read_jsonl(self.test_path), set_type="test") + + @classmethod + def _create_examples(cls, lines, set_type): + examples = [] + for line in lines: + examples.append( + Example( + # NOTE: RteTask.super_glue_format_preds() is dependent on this guid format. + guid="%s-%s" % (set_type, line["idx"]), + input_premise=line["premise"], + input_hypothesis=line["hypothesis"], + label=line["label"] if set_type != "test" else cls.LABELS[-1], + ) + ) + return examples + + @classmethod + def super_glue_format_preds(cls, pred_dict): + """Reformat this task's raw predictions to have the structure expected by SuperGLUE.""" + lines = [] + for pred, guid in zip(list(pred_dict["preds"]), list(pred_dict["guids"])): + lines.append({"idx": int(guid.split("-")[1]), "label": cls.LABELS[pred]}) + return lines diff --git a/jiant/tasks/lib/scitail.py b/jiant/tasks/lib/scitail.py new file mode 100644 index 000000000..da9e1dcc7 --- /dev/null +++ b/jiant/tasks/lib/scitail.py @@ -0,0 +1,104 @@ +import numpy as np +import torch +from dataclasses import dataclass +from typing import List + +from jiant.tasks.core import ( + BaseExample, + BaseTokenizedExample, + BaseDataRow, + BatchMixin, + Task, + TaskTypes, +) +from jiant.tasks.lib.templates.shared import labels_to_bimap, double_sentence_featurize +from jiant.utils.python.io import read_jsonl + + +@dataclass +class Example(BaseExample): + guid: str + input_premise: str + input_hypothesis: str + label: str + + def tokenize(self, tokenizer): + return TokenizedExample( + guid=self.guid, + input_premise=tokenizer.tokenize(self.input_premise), + input_hypothesis=tokenizer.tokenize(self.input_hypothesis), + label_id=SciTailTask.LABEL_TO_ID[self.label], + ) + + +@dataclass +class TokenizedExample(BaseTokenizedExample): + guid: str + input_premise: List + input_hypothesis: List + label_id: int + + def featurize(self, tokenizer, feat_spec): + return double_sentence_featurize( + guid=self.guid, + input_tokens_a=self.input_premise, + input_tokens_b=self.input_hypothesis, + label_id=self.label_id, + tokenizer=tokenizer, + feat_spec=feat_spec, + data_row_class=DataRow, + ) + + +@dataclass +class DataRow(BaseDataRow): + guid: str + input_ids: np.ndarray + input_mask: np.ndarray + segment_ids: np.ndarray + label_id: int + tokens: list + + +@dataclass +class Batch(BatchMixin): + input_ids: torch.LongTensor + input_mask: torch.LongTensor + segment_ids: torch.LongTensor + label_id: torch.LongTensor + tokens: list + + +class SciTailTask(Task): + Example = Example + TokenizedExample = Example + DataRow = DataRow + Batch = Batch + + TASK_TYPE = TaskTypes.CLASSIFICATION + LABELS = ["entails", "neutral"] + + LABEL_TO_ID, ID_TO_LABEL = labels_to_bimap(LABELS) + + def get_train_examples(self): + return self._create_examples(lines=read_jsonl(self.train_path), set_type="train") + + def get_val_examples(self): + return self._create_examples(lines=read_jsonl(self.val_path), set_type="val") + + def get_test_examples(self): + return self._create_examples(lines=read_jsonl(self.test_path), set_type="test") + + @classmethod + def _create_examples(cls, lines, set_type): + examples = [] + for line in lines: + examples.append( + Example( + guid="%s-%s" % (set_type, len(examples)), + input_premise=line["premise"], + input_hypothesis=line["hypothesis"], + label=line["label"] if set_type != "test" else cls.LABELS[-1], + ) + ) + return examples diff --git a/jiant/tasks/lib/senteval/__init__.py b/jiant/tasks/lib/senteval/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/jiant/tasks/lib/senteval/tense.py b/jiant/tasks/lib/senteval/tense.py new file mode 100644 index 000000000..96d77cc79 --- /dev/null +++ b/jiant/tasks/lib/senteval/tense.py @@ -0,0 +1,99 @@ +import numpy as np +import pandas as pd +import torch +from dataclasses import dataclass +from typing import List + +from jiant.tasks.core import ( + BaseExample, + BaseTokenizedExample, + BaseDataRow, + BatchMixin, + Task, + TaskTypes, +) +from jiant.tasks.lib.templates.shared import single_sentence_featurize, labels_to_bimap + + +@dataclass +class Example(BaseExample): + guid: str + text: str + label: str + + def tokenize(self, tokenizer): + return TokenizedExample( + guid=self.guid, + text=tokenizer.tokenize(self.text), + label_id=SentevalTenseTask.LABEL_TO_ID[self.label], + ) + + +@dataclass +class TokenizedExample(BaseTokenizedExample): + guid: str + text: List + label_id: int + + def featurize(self, tokenizer, feat_spec): + return single_sentence_featurize( + guid=self.guid, + input_tokens=self.text, + label_id=self.label_id, + tokenizer=tokenizer, + feat_spec=feat_spec, + data_row_class=DataRow, + ) + + +@dataclass +class DataRow(BaseDataRow): + guid: str + input_ids: np.ndarray + input_mask: np.ndarray + segment_ids: np.ndarray + label_id: int + tokens: list + + +@dataclass +class Batch(BatchMixin): + input_ids: torch.LongTensor + input_mask: torch.LongTensor + segment_ids: torch.LongTensor + label_id: torch.LongTensor + tokens: list + + +class SentevalTenseTask(Task): + Example = Example + TokenizedExample = TokenizedExample + DataRow = DataRow + Batch = Batch + + TASK_TYPE = TaskTypes.CLASSIFICATION + LABELS = ["PAST", "PRES"] + LABEL_TO_ID, ID_TO_LABEL = labels_to_bimap(LABELS) + + def get_train_examples(self): + return self._create_examples(path=self.train_path, set_type="train") + + def get_val_examples(self): + return self._create_examples(path=self.val_path, set_type="val") + + def get_test_examples(self): + return self._create_examples(path=self.test_path, set_type="test") + + @classmethod + def _create_examples(cls, path, set_type): + examples = [] + df = pd.read_csv(path, index_col=0, names=["split", "label", "text", "unk_1", "unk_2"]) + for i, row in df.iterrows(): + examples.append( + Example( + guid="%s-%s" % (set_type, i), + text=row.text, + label=row.label if set_type != "test" else cls.LABELS[-1], + ) + ) + return examples diff --git a/jiant/tasks/lib/snli.py b/jiant/tasks/lib/snli.py new file mode 100644 index 000000000..197087b94 --- /dev/null +++ b/jiant/tasks/lib/snli.py @@ -0,0 +1,119 @@ +import numpy as np +import torch +from dataclasses import dataclass +from typing import List + +from jiant.tasks.core import ( + BaseExample, + BaseTokenizedExample, + BaseDataRow, + BatchMixin, + Task, + TaskTypes, +) +from jiant.tasks.lib.templates.shared import double_sentence_featurize, labels_to_bimap +from jiant.utils.python.io import read_jsonl + + +@dataclass +class Example(BaseExample): + guid: str + input_premise: str + input_hypothesis: str + label: str + + def tokenize(self, tokenizer): + return TokenizedExample( + guid=self.guid, + input_premise=tokenizer.tokenize(self.input_premise), + input_hypothesis=tokenizer.tokenize(self.input_hypothesis), + label_id=SnliTask.LABEL_TO_ID[self.label], + ) + + +@dataclass +class TokenizedExample(BaseTokenizedExample): + guid: str + input_premise: List + input_hypothesis: List + label_id: int + + def featurize(self, tokenizer, feat_spec): + return double_sentence_featurize( + guid=self.guid, + input_tokens_a=self.input_premise, + input_tokens_b=self.input_hypothesis, + label_id=self.label_id, + tokenizer=tokenizer, + feat_spec=feat_spec, + data_row_class=DataRow, + ) + + +@dataclass +class DataRow(BaseDataRow): + guid: str + input_ids: np.ndarray + input_mask: np.ndarray + segment_ids: np.ndarray + label_id: int + tokens: list + + +@dataclass +class Batch(BatchMixin): + input_ids: torch.LongTensor + input_mask: torch.LongTensor + segment_ids: torch.LongTensor + label_id: torch.LongTensor + tokens: list + + +class SnliTask(Task): + Example = Example + TokenizedExample = Example + DataRow = DataRow + Batch = Batch + + TASK_TYPE = TaskTypes.CLASSIFICATION + LABELS = ["contradiction", "entailment", "neutral"] + LABEL_TO_ID, ID_TO_LABEL = labels_to_bimap(LABELS) + + def get_train_examples(self): + return self._create_examples(lines=read_jsonl(self.train_path), set_type="train") + + def get_val_examples(self): + return self._create_examples(lines=read_jsonl(self.val_path), set_type="val") + + def get_test_examples(self): + return self._create_examples(lines=read_jsonl(self.test_path), set_type="test") + + @classmethod + def _create_examples(cls, lines, set_type): + examples = [] + for (i, line) in enumerate(lines): + if "gold_label" in line: + # Loading from original data + if line["gold_label"] == "-": + continue + examples.append( + Example( + guid="%s-%s" % (set_type, i), + input_premise=line["sentence1"], + input_hypothesis=line["sentence2"], + label=line["gold_label"] if set_type != "test" else cls.LABELS[-1], + ) + ) + else: + # Loading from NLP data + if line["label"] == -1: + continue + examples.append( + Example( + guid="%s-%s" % (set_type, i), + input_premise=line["premise"], + input_hypothesis=line["hypothesis"], + label=line["label"] if set_type != "test" else cls.LABELS[-1], + ) + ) + return examples diff --git a/jiant/tasks/lib/socialiqa.py b/jiant/tasks/lib/socialiqa.py new file mode 100644 index 000000000..dc3fe3692 --- /dev/null +++ b/jiant/tasks/lib/socialiqa.py @@ -0,0 +1,78 @@ +from dataclasses import dataclass + +from jiant.tasks.lib.templates.shared import labels_to_bimap +from jiant.tasks.lib.templates import multiple_choice as mc_template +from jiant.utils.python.io import read_json_lines, read_file_lines + + +@dataclass +class Example(mc_template.Example): + @property + def task(self): + return SocialIQATask + + +@dataclass +class TokenizedExample(mc_template.TokenizedExample): + pass + + +@dataclass +class DataRow(mc_template.DataRow): + pass + + +@dataclass +class Batch(mc_template.Batch): + pass + + +class SocialIQATask(mc_template.AbstractMultipleChoiceTask): + Example = Example + TokenizedExample = Example + DataRow = DataRow + Batch = Batch + + CHOICE_KEYS = ["A", "B", "C"] + CHOICE_TO_ID, ID_TO_CHOICE = labels_to_bimap(CHOICE_KEYS) + NUM_CHOICES = len(CHOICE_KEYS) + + def get_train_examples(self): + return self._create_examples(lines=read_json_lines(self.train_path), set_type="train") + + def get_val_examples(self): + return self._create_examples(lines=read_json_lines(self.val_path), set_type="val") + + def get_test_examples(self): + return self._create_examples(lines=read_json_lines(self.test_path), set_type="test") + + @classmethod + def _create_examples(cls, lines, set_type): + examples = [] + answer_key_ls = ["answerA", "answerB", "answerC"] + nlp_label_map = { + "1\n": "A", + "2\n": "B", + "3\n": "C", + } + for i, line in enumerate(lines): + if "label" in line: + # Loading from NLP data + label = nlp_label_map[line["label"]] + else: + # Loading from original data + label = line["correct"] + examples.append( + Example( + guid="%s-%s" % (set_type, i), + prompt=line["context"] + " " + line["question"], + choice_list=[line[answer_key] for answer_key in answer_key_ls], + label=label, + ) + ) + return examples + + @classmethod + def _read_labels(cls, path): + lines = read_file_lines(path) + return [int(line.strip()) for line in lines] diff --git a/jiant/tasks/lib/squad.py b/jiant/tasks/lib/squad.py new file mode 100644 index 000000000..3d9e46673 --- /dev/null +++ b/jiant/tasks/lib/squad.py @@ -0,0 +1,25 @@ +from dataclasses import dataclass + +from jiant.tasks.lib.templates.squad_style import core as squad_style_template + + +@dataclass +class Example(squad_style_template.Example): + def tokenize(self, tokenizer): + raise NotImplementedError("SQuaD is weird") + + +@dataclass +class DataRow(squad_style_template.DataRow): + pass + + +@dataclass +class Batch(squad_style_template.Batch): + pass + + +class SquadTask(squad_style_template.BaseSquadStyleTask): + Example = Example + DataRow = DataRow + Batch = Batch diff --git a/jiant/tasks/lib/sst.py b/jiant/tasks/lib/sst.py new file mode 100644 index 000000000..2033f297c --- /dev/null +++ b/jiant/tasks/lib/sst.py @@ -0,0 +1,99 @@ +import numpy as np +import torch +from dataclasses import dataclass +from typing import List + +from jiant.tasks.core import ( + BaseExample, + BaseTokenizedExample, + BaseDataRow, + BatchMixin, + GlueMixin, + Task, + TaskTypes, +) +from jiant.tasks.lib.templates.shared import single_sentence_featurize, labels_to_bimap +from jiant.utils.python.io import read_jsonl + + +@dataclass +class Example(BaseExample): + guid: str + text: str + label: str + + def tokenize(self, tokenizer): + return TokenizedExample( + guid=self.guid, + text=tokenizer.tokenize(self.text), + label_id=SstTask.LABEL_TO_ID[self.label], + ) + + +@dataclass +class TokenizedExample(BaseTokenizedExample): + guid: str + text: List + label_id: int + + def featurize(self, tokenizer, feat_spec): + return single_sentence_featurize( + guid=self.guid, + input_tokens=self.text, + label_id=self.label_id, + tokenizer=tokenizer, + feat_spec=feat_spec, + data_row_class=DataRow, + ) + + +@dataclass +class DataRow(BaseDataRow): + guid: str + input_ids: np.ndarray + input_mask: np.ndarray + segment_ids: np.ndarray + label_id: int + tokens: list + + +@dataclass +class Batch(BatchMixin): + input_ids: torch.LongTensor + input_mask: torch.LongTensor + segment_ids: torch.LongTensor + label_id: torch.LongTensor + tokens: list + + +class SstTask(GlueMixin, Task): + Example = Example + TokenizedExample = Example + DataRow = DataRow + Batch = Batch + + TASK_TYPE = TaskTypes.CLASSIFICATION + LABELS = ["0", "1"] + LABEL_TO_ID, ID_TO_LABEL = labels_to_bimap(LABELS) + + def get_train_examples(self): + return self._create_examples(lines=read_jsonl(self.train_path), set_type="train") + + def get_val_examples(self): + return self._create_examples(lines=read_jsonl(self.val_path), set_type="val") + + def get_test_examples(self): + return self._create_examples(lines=read_jsonl(self.test_path), set_type="test") + + @classmethod + def _create_examples(cls, lines, set_type): + examples = [] + for (i, line) in enumerate(lines): + examples.append( + Example( + guid="%s-%s" % (set_type, i), + text=line["text"], + label=line["label"] if set_type != "test" else cls.LABELS[-1], + ) + ) + return examples diff --git a/jiant/tasks/lib/stsb.py b/jiant/tasks/lib/stsb.py new file mode 100644 index 000000000..f5289c0d5 --- /dev/null +++ b/jiant/tasks/lib/stsb.py @@ -0,0 +1,127 @@ +import numpy as np +import torch +from dataclasses import dataclass +from typing import List + +from jiant.tasks.core import ( + BaseExample, + BaseTokenizedExample, + BaseDataRow, + BatchMixin, + GlueMixin, + Task, + TaskTypes, +) +from jiant.tasks.lib.templates.shared import ( + construct_double_input_tokens_and_segment_ids, + create_input_set_from_tokens_and_segments, +) +from jiant.utils.python.io import read_jsonl + + +@dataclass +class Example(BaseExample): + guid: str + text_a: str + text_b: str + label: float + + def tokenize(self, tokenizer): + return TokenizedExample( + guid=self.guid, + text_a=tokenizer.tokenize(self.text_a), + text_b=tokenizer.tokenize(self.text_b), + label=self.label, + ) + + +@dataclass +class TokenizedExample(BaseTokenizedExample): + guid: str + text_a: List + text_b: List + label: float + + def featurize(self, tokenizer, feat_spec): + # Label not label_id, otherwise we can use double_sentence_featurize + unpadded_inputs = construct_double_input_tokens_and_segment_ids( + input_tokens_a=self.text_a, + input_tokens_b=self.text_b, + tokenizer=tokenizer, + feat_spec=feat_spec, + ) + input_set = create_input_set_from_tokens_and_segments( + unpadded_tokens=unpadded_inputs.unpadded_tokens, + unpadded_segment_ids=unpadded_inputs.unpadded_segment_ids, + tokenizer=tokenizer, + feat_spec=feat_spec, + ) + return DataRow( + guid=self.guid, + input_ids=np.array(input_set.input_ids), + input_mask=np.array(input_set.input_mask), + segment_ids=np.array(input_set.segment_ids), + label=self.label, + tokens=unpadded_inputs.unpadded_tokens, + ) + + +@dataclass +class DataRow(BaseDataRow): + guid: str + input_ids: np.ndarray + input_mask: np.ndarray + segment_ids: np.ndarray + label: float + tokens: list + + +@dataclass +class Batch(BatchMixin): + input_ids: torch.LongTensor + input_mask: torch.LongTensor + segment_ids: torch.LongTensor + label: torch.FloatTensor + tokens: list + + +class StsbTask(GlueMixin, Task): + Example = Example + TokenizedExample = Example + DataRow = DataRow + Batch = Batch + + TASK_TYPE = TaskTypes.REGRESSION + + def get_train_examples(self): + return self._create_examples(lines=read_jsonl(self.train_path), set_type="train") + + def get_val_examples(self): + return self._create_examples(lines=read_jsonl(self.val_path), set_type="val") + + def get_test_examples(self): + return self._create_examples(lines=read_jsonl(self.test_path), set_type="test") + + @classmethod + def _create_examples(cls, lines, set_type): + examples = [] + for (i, line) in enumerate(lines): + examples.append( + Example( + guid="%s-%s" % (set_type, i), + text_a=line["text_a"], + text_b=line["text_b"], + label=float(line["label"]) if set_type != "test" else 0, + ) + ) + return examples + + @classmethod + def get_glue_preds(cls, pred_dict): + """Returns a tuple of (index, prediction) as expected by GLUE.""" + indexes = [] + predictions = [] + for pred, guid in zip(list(pred_dict["preds"]), list(pred_dict["guids"])): + indexes.append(int(guid.split("-")[1])) + predictions.append(str(round(pred, 3))) + return (indexes, predictions) diff --git a/jiant/tasks/lib/superglue_axb.py b/jiant/tasks/lib/superglue_axb.py new file mode 100644 index 000000000..2b8da670c --- /dev/null +++ b/jiant/tasks/lib/superglue_axb.py @@ -0,0 +1,31 @@ +from dataclasses import dataclass + +from . import rte + + +@dataclass +class Example(rte.Example): + pass + + +@dataclass +class TokenizedExample(rte.Example): + pass + + +@dataclass +class DataRow(rte.DataRow): + pass + + +@dataclass +class Batch(rte.Batch): + pass + + +class SuperglueBroadcoverageDiagnosticsTask(rte.RteTask): + def get_train_examples(self): + raise RuntimeError("This task does not support training examples") + + def get_val_examples(self): + raise RuntimeError("This task does not support validation examples") diff --git a/jiant/tasks/lib/superglue_axg.py b/jiant/tasks/lib/superglue_axg.py new file mode 100644 index 000000000..5a8ed9565 --- /dev/null +++ b/jiant/tasks/lib/superglue_axg.py @@ -0,0 +1,31 @@ +from dataclasses import dataclass + +from . import rte + + +@dataclass +class Example(rte.Example): + pass + + +@dataclass +class TokenizedExample(rte.Example): + pass + + +@dataclass +class DataRow(rte.DataRow): + pass + + +@dataclass +class Batch(rte.Batch): + pass + + +class SuperglueWinogenderDiagnosticsTask(rte.RteTask): + def get_train_examples(self): + raise RuntimeError("This task does not support training examples") + + def get_val_examples(self): + raise RuntimeError("This task does not support validation examples") diff --git a/jiant/tasks/lib/swag.py b/jiant/tasks/lib/swag.py new file mode 100644 index 000000000..b83f247f2 --- /dev/null +++ b/jiant/tasks/lib/swag.py @@ -0,0 +1,67 @@ +import pandas as pd +from dataclasses import dataclass + +from jiant.tasks.lib.templates.shared import labels_to_bimap +from jiant.tasks.lib.templates import multiple_choice as mc_template + + +@dataclass +class Example(mc_template.Example): + @property + def task(self): + return SWAGTask + + +@dataclass +class TokenizedExample(mc_template.TokenizedExample): + pass + + +@dataclass +class DataRow(mc_template.DataRow): + pass + + +@dataclass +class Batch(mc_template.Batch): + pass + + +class SWAGTask(mc_template.AbstractMultipleChoiceTask): + Example = Example + TokenizedExample = Example + DataRow = DataRow + Batch = Batch + + CHOICE_KEYS = [0, 1, 2, 3] + CHOICE_TO_ID, ID_TO_CHOICE = labels_to_bimap(CHOICE_KEYS) + NUM_CHOICES = len(CHOICE_KEYS) + + def get_train_examples(self): + return self._create_examples(path=self.train_path, set_type="train") + + def get_val_examples(self): + return self._create_examples(path=self.val_path, set_type="val") + + def get_test_examples(self): + return self._create_examples(path=self.test_path, set_type="test") + + @classmethod + def _create_examples(cls, path, set_type): + df = pd.read_csv(path) + examples = [] + for i, row in enumerate(df.itertuples()): + examples.append( + Example( + guid="%s-%s" % (set_type, i), + prompt=row.sent1, + choice_list=[ + row.sent2 + " " + row.ending0, + row.sent2 + " " + row.ending1, + row.sent2 + " " + row.ending2, + row.sent2 + " " + row.ending3, + ], + label=row.label if set_type != "test" else cls.CHOICE_KEYS[-1], + ) + ) + return examples diff --git a/jiant/tasks/lib/tatoeba.py b/jiant/tasks/lib/tatoeba.py new file mode 100644 index 000000000..90ef9f56d --- /dev/null +++ b/jiant/tasks/lib/tatoeba.py @@ -0,0 +1,134 @@ +import numpy as np +import torch +from dataclasses import dataclass +from typing import List + + +from jiant.tasks.core import ( + BaseExample, + BaseTokenizedExample, + BaseDataRow, + BatchMixin, + Task, + TaskTypes, +) +from jiant.tasks.lib.templates.shared import ( + construct_single_input_tokens_and_segment_ids, + create_input_set_from_tokens_and_segments, + labels_to_bimap, +) +from jiant.utils.python.io import read_file, read_file_lines + + +@dataclass +class Example(BaseExample): + guid: str + is_english: bool + text: str + + def tokenize(self, tokenizer): + return TokenizedExample( + guid=self.guid, is_english=self.is_english, text_tokens=tokenizer.tokenize(self.text), + ) + + +@dataclass +class TokenizedExample(BaseTokenizedExample): + guid: str + is_english: bool + text_tokens: List + + def featurize(self, tokenizer, feat_spec): + unpadded_inputs = construct_single_input_tokens_and_segment_ids( + input_tokens=self.text_tokens, tokenizer=tokenizer, feat_spec=feat_spec, + ) + input_set = create_input_set_from_tokens_and_segments( + unpadded_tokens=unpadded_inputs.unpadded_tokens, + unpadded_segment_ids=unpadded_inputs.unpadded_segment_ids, + tokenizer=tokenizer, + feat_spec=feat_spec, + ) + return DataRow( + guid=self.guid, + input_ids=np.array(input_set.input_ids), + input_mask=np.array(input_set.input_mask), + segment_ids=np.array(input_set.segment_ids), + is_english=self.is_english, + tokens=unpadded_inputs.unpadded_tokens, + ) + + +@dataclass +class DataRow(BaseDataRow): + guid: str + input_ids: np.ndarray + input_mask: np.ndarray + segment_ids: np.ndarray + is_english: bool + tokens: list + + +@dataclass +class Batch(BatchMixin): + input_ids: torch.LongTensor + input_mask: torch.LongTensor + segment_ids: torch.LongTensor + is_english: torch.BoolTensor + tokens: list + + +class TatoebaTask(Task): + Example = Example + TokenizedExample = Example + DataRow = DataRow + Batch = Batch + + TASK_TYPE = TaskTypes.EMBEDDING + + def __init__(self, name, path_dict, language): + super().__init__(name=name, path_dict=path_dict) + self.language = language + self.lang_bimap = labels_to_bimap(["en", language]) + + def get_train_examples(self): + raise RuntimeError("This task does not support train examples") + + def get_val_examples(self): + eng_examples = self._create_examples( + lines=read_file_lines(self.path_dict["eng"]), is_english=True, set_type="val", + ) + other_examples = self._create_examples( + lines=read_file_lines(self.path_dict["other"]), is_english=False, set_type="val", + ) + return eng_examples + other_examples + + def get_test_examples(self): + raise RuntimeError("This task does not support test examples") + + def get_val_labels(self): + return np.array( + [int(x) for x in read_file(self.path_dict["labels_path"]).strip().splitlines()] + ) + + @classmethod + def _create_examples(cls, lines, is_english, set_type): + examples = [] + for (i, line) in enumerate(lines): + examples.append( + Example(guid="%s-%s" % (set_type, i), is_english=is_english, text=line,) + ) + return examples + + +def similarity_search(x, y, dim, normalize=False): + import faiss + + x = x.copy() + y = y.copy() + idx = faiss.IndexFlatL2(dim) + if normalize: + faiss.normalize_L2(x) + faiss.normalize_L2(y) + idx.add(x) + scores, prediction = idx.search(y, 1) + return prediction diff --git a/jiant/tasks/lib/templates/__init__.py b/jiant/tasks/lib/templates/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/jiant/tasks/lib/templates/edge_probing_single_span.py b/jiant/tasks/lib/templates/edge_probing_single_span.py new file mode 100644 index 000000000..3043a165a --- /dev/null +++ b/jiant/tasks/lib/templates/edge_probing_single_span.py @@ -0,0 +1,144 @@ +"""Single-span edge-probing task base class. + +This module defines an AbstractProbingTask and inheritable logic for tokenization and featurization. +Single-span edge-probing tasks should inherit from AbstractProbingTask and the dataclasses +defined here. + +""" +from abc import ABC + +import numpy as np +import torch +from dataclasses import dataclass +from typing import List, Tuple + +from jiant.tasks.core import ( + BaseExample, + BaseTokenizedExample, + BaseDataRow, + BatchMixin, + Task, + TaskTypes, +) +from jiant.tasks.lib.templates.shared import ( + create_input_set_from_tokens_and_segments, + add_cls_token, +) +from jiant.tasks.utils import ExclusiveSpan, truncate_sequences +from jiant.utils import retokenize +from jiant.utils.tokenization_normalization import normalize_tokenizations + + +@dataclass +class Example(BaseExample): + guid: str + text: str + span: List[int] + labels: List[str] + + @property + def task(self): + raise NotImplementedError() + + def tokenize(self, tokenizer): + space_tokenization = self.text.split() + target_tokenization = tokenizer.tokenize(self.text) + normed_space_tokenization, normed_target_tokenization = normalize_tokenizations( + space_tokenization, target_tokenization, tokenizer + ) + aligner = retokenize.TokenAligner(normed_space_tokenization, normed_target_tokenization) + target_span = aligner.project_token_span(self.span[0], self.span[1]) + return TokenizedExample( + guid=self.guid, + tokens=target_tokenization, + span=target_span, + span_text=" ".join(target_tokenization[target_span[0] : target_span[1]]), + label_ids=[self.task.LABEL_TO_ID[label] for label in self.labels], + label_num=len(self.task.LABELS), + ) + + +@dataclass +class TokenizedExample(BaseTokenizedExample): + guid: str + tokens: List[str] + span: Tuple[int, int] + span_text: str + label_ids: List[int] + label_num: int + + def featurize(self, tokenizer, feat_spec): + special_tokens_count = 2 # CLS, SEP + + (tokens,) = truncate_sequences( + tokens_ls=[self.tokens], max_length=feat_spec.max_seq_length - special_tokens_count, + ) + + unpadded_tokens = tokens + [tokenizer.sep_token] + unpadded_segment_ids = [feat_spec.sequence_a_segment_id] * (len(tokens) + 1) + + unpadded_inputs = add_cls_token( + unpadded_tokens=unpadded_tokens, + unpadded_segment_ids=unpadded_segment_ids, + tokenizer=tokenizer, + feat_spec=feat_spec, + ) + + input_set = create_input_set_from_tokens_and_segments( + unpadded_tokens=unpadded_inputs.unpadded_tokens, + unpadded_segment_ids=unpadded_inputs.unpadded_segment_ids, + tokenizer=tokenizer, + feat_spec=feat_spec, + ) + + # exclusive spans are converted to inclusive spans for use with SelfAttentiveSpanExtractor + span = ExclusiveSpan( + start=self.span[0] + unpadded_inputs.cls_offset, + end=self.span[1] + unpadded_inputs.cls_offset, + ).to_inclusive() + + binary_label_ids = np.zeros((self.label_num,), dtype=int) + for label_id in self.label_ids: + binary_label_ids[label_id] = 1 + + return DataRow( + guid=self.guid, + input_ids=np.array(input_set.input_ids), + input_mask=np.array(input_set.input_mask), + segment_ids=np.array(input_set.segment_ids), + spans=np.array([span]), + label_ids=binary_label_ids, + tokens=unpadded_inputs.unpadded_tokens, + span_text=self.span_text, + ) + + +@dataclass +class DataRow(BaseDataRow): + guid: str + input_ids: np.ndarray + input_mask: np.ndarray + segment_ids: np.ndarray + spans: np.ndarray + label_ids: np.ndarray + tokens: List + span_text: str + + +@dataclass +class Batch(BatchMixin): + input_ids: torch.LongTensor + input_mask: torch.LongTensor + segment_ids: torch.LongTensor + spans: torch.LongTensor + label_ids: torch.LongTensor + tokens: List + span_text: List + + +class AbstractProbingTask(Task, ABC): + TASK_TYPE = TaskTypes.MULTI_LABEL_SPAN_CLASSIFICATION + + LABELS = NotImplemented + LABEL_TO_ID = NotImplemented + ID_TO_LABEL = NotImplemented diff --git a/jiant/tasks/lib/templates/edge_probing_two_span.py b/jiant/tasks/lib/templates/edge_probing_two_span.py new file mode 100644 index 000000000..e5337af6d --- /dev/null +++ b/jiant/tasks/lib/templates/edge_probing_two_span.py @@ -0,0 +1,158 @@ +"""Two-span, multi-label edge-probing task base class. + +This module defines an AbstractProbingTask and inheritable logic for tokenization and featurization. +Two-span, multi-label edge-probing tasks should inherit from AbstractProbingTask and the dataclasses +defined here. See spr1.py for an example task implementation inheriting from this module. + +""" +from abc import ABC + +import numpy as np +import torch +from dataclasses import dataclass +from typing import List, Tuple + +from jiant.tasks.core import ( + BaseExample, + BaseTokenizedExample, + BaseDataRow, + BatchMixin, + Task, + TaskTypes, +) +from jiant.tasks.lib.templates.shared import ( + create_input_set_from_tokens_and_segments, + add_cls_token, +) +from jiant.tasks.utils import ExclusiveSpan, truncate_sequences +from jiant.utils import retokenize +from jiant.utils.tokenization_normalization import normalize_tokenizations + + +@dataclass +class Example(BaseExample): + guid: str + text: str + span1: List[int] + span2: List[int] + labels: List[str] + + @property + def task(self): + raise NotImplementedError() + + def tokenize(self, tokenizer): + space_tokenization = self.text.split() + target_tokenization = tokenizer.tokenize(self.text) + normed_space_tokenization, normed_target_tokenization = normalize_tokenizations( + space_tokenization, target_tokenization, tokenizer + ) + aligner = retokenize.TokenAligner(normed_space_tokenization, normed_target_tokenization) + target_span1 = aligner.project_token_span(self.span1[0], self.span1[1]) + target_span2 = aligner.project_token_span(self.span2[0], self.span2[1]) + return TokenizedExample( + guid=self.guid, + tokens=target_tokenization, + span1_span=target_span1, + span2_span=target_span2, + span1_text=" ".join(target_tokenization[target_span1[0] : target_span1[1]]), + span2_text=" ".join(target_tokenization[target_span2[0] : target_span2[1]]), + label_ids=[self.task.LABEL_TO_ID[label] for label in self.labels], + label_num=len(self.task.LABELS), + ) + + +@dataclass +class TokenizedExample(BaseTokenizedExample): + guid: str + tokens: List[str] + span1_span: Tuple[int, int] + span2_span: Tuple[int, int] + span1_text: str + span2_text: str + label_ids: List[int] + label_num: int + + def featurize(self, tokenizer, feat_spec): + special_tokens_count = 2 # CLS, SEP + + (tokens,) = truncate_sequences( + tokens_ls=[self.tokens], max_length=feat_spec.max_seq_length - special_tokens_count, + ) + + unpadded_tokens = tokens + [tokenizer.sep_token] + unpadded_segment_ids = [feat_spec.sequence_a_segment_id] * (len(tokens) + 1) + + unpadded_inputs = add_cls_token( + unpadded_tokens=unpadded_tokens, + unpadded_segment_ids=unpadded_segment_ids, + tokenizer=tokenizer, + feat_spec=feat_spec, + ) + + input_set = create_input_set_from_tokens_and_segments( + unpadded_tokens=unpadded_inputs.unpadded_tokens, + unpadded_segment_ids=unpadded_inputs.unpadded_segment_ids, + tokenizer=tokenizer, + feat_spec=feat_spec, + ) + + # exclusive spans are converted to inclusive spans for use with SelfAttentiveSpanExtractor + span1_span = ExclusiveSpan( + start=self.span1_span[0] + unpadded_inputs.cls_offset, + end=self.span1_span[1] + unpadded_inputs.cls_offset, + ).to_inclusive() + + span2_span = ExclusiveSpan( + start=self.span2_span[0] + unpadded_inputs.cls_offset, + end=self.span2_span[1] + unpadded_inputs.cls_offset, + ).to_inclusive() + + binary_label_ids = np.zeros((self.label_num,), dtype=int) + for label_id in self.label_ids: + binary_label_ids[label_id] = 1 + + return DataRow( + guid=self.guid, + input_ids=np.array(input_set.input_ids), + input_mask=np.array(input_set.input_mask), + segment_ids=np.array(input_set.segment_ids), + spans=np.array([span1_span, span2_span]), + label_ids=binary_label_ids, + tokens=unpadded_inputs.unpadded_tokens, + span1_text=self.span1_text, + span2_text=self.span2_text, + ) + + +@dataclass +class DataRow(BaseDataRow): + guid: str + input_ids: np.ndarray + input_mask: np.ndarray + segment_ids: np.ndarray + spans: np.ndarray + label_ids: np.ndarray + tokens: List + span1_text: str + span2_text: str + + +@dataclass +class Batch(BatchMixin): + input_ids: torch.LongTensor + input_mask: torch.LongTensor + segment_ids: torch.LongTensor + spans: torch.LongTensor + label_ids: torch.LongTensor + tokens: List + span1_text: List + span2_text: List + + +class AbstractProbingTask(Task, ABC): + TASK_TYPE = TaskTypes.MULTI_LABEL_SPAN_CLASSIFICATION + + LABELS = NotImplemented + LABEL_TO_ID = NotImplemented + ID_TO_LABEL = NotImplemented diff --git a/jiant/tasks/lib/templates/hacky_tokenization_matching.py b/jiant/tasks/lib/templates/hacky_tokenization_matching.py new file mode 100644 index 000000000..ca1fdd7b9 --- /dev/null +++ b/jiant/tasks/lib/templates/hacky_tokenization_matching.py @@ -0,0 +1,125 @@ +"""TODO: Remove when Tokenizers gets better (Issue #43)""" +import transformers +from jiant.tasks.utils import ExclusiveSpan + + +def map_tags_to_token_position(flat_stripped, indices, split_text): + char_index = 0 + current_string = flat_stripped + positions = [None] * len(split_text) + for i, token in enumerate(split_text): + found_index = current_string.find(token.lower()) + assert found_index != -1 + positions[i] = indices[char_index + found_index] + char_index += found_index + len(token) + current_string = flat_stripped[char_index:] + for elem in positions: + assert elem is not None + return positions + + +def convert_mapped_tags(positions, tag_ids, length): + labels = [None] * length + mask = [0] * length + for pos, tag_id in zip(positions, tag_ids): + labels[pos] = tag_id + mask[pos] = 1 + return labels, mask + + +def input_flat_strip(tokens): + return "".join(tokens).lower() + + +def delegate_flat_strip(tokens, tokenizer, return_indices=False): + if isinstance(tokenizer, transformers.BertTokenizer): + return bert_flat_strip(tokens=tokens, return_indices=return_indices) + elif isinstance(tokenizer, transformers.RobertaTokenizer): + return roberta_flat_strip(tokens=tokens, return_indices=return_indices) + elif isinstance(tokenizer, transformers.AlbertTokenizer): + return albert_flat_strip(tokens=tokens, return_indices=return_indices) + elif isinstance(tokenizer, transformers.XLMRobertaTokenizer): + return xlm_roberta_flat_strip(tokens=tokens, return_indices=return_indices) + else: + raise KeyError(type(tokenizer)) + + +def bert_flat_strip(tokens, return_indices=False): + ls = [] + count = 0 + indices = [] + for token in tokens: + if token.startswith("##"): + token = token.replace("##", "") + else: + pass + ls.append(token) + indices += [count] * len(token) + count += 1 + string = "".join(ls).lower() + if return_indices: + return string, indices + else: + return string + + +def roberta_flat_strip(tokens, return_indices=False): + ls = [] + count = 0 + indices = [] + for token in tokens: + if token.startswith("Ġ"): + token = token.replace("Ġ", "") + else: + pass + ls.append(token) + indices += [count] * len(token) + count += 1 + string = "".join(ls).lower() + if return_indices: + return string, indices + else: + return string + + +def xlm_roberta_flat_strip(tokens, return_indices=False): + # TODO: Refactor to use general SentencePiece function (Issue #53) + return albert_flat_strip(tokens=tokens, return_indices=return_indices) + + +def albert_flat_strip(tokens, return_indices=False): + ls = [] + count = 0 + indices = [] + for token in tokens: + token = token.replace('"', "``") + if token.startswith("▁"): + token = token[1:] + else: + pass + ls.append(token) + indices += [count] * len(token) + count += 1 + string = "".join(ls).lower() + if return_indices: + return string, indices + else: + return string + + +def starts_with(ls, prefix): + return ls[: len(prefix)] == prefix + + +def get_token_span(sentence, span: ExclusiveSpan, tokenizer): + tokenized = tokenizer.tokenize(sentence) + tokenized_start1 = tokenizer.tokenize(sentence[: span.start]) + tokenized_start2 = tokenizer.tokenize(sentence[: span.end]) + assert starts_with(tokenized, tokenized_start1) + # assert starts_with(tokenized, tokenized_start2) # <- fails because of "does" in "doesn't" + word = sentence[span.to_slice()] + assert word.lower().replace(" ", "") in delegate_flat_strip( + tokenized_start2[len(tokenized_start1) :], tokenizer=tokenizer, + ) + token_span = ExclusiveSpan(start=len(tokenized_start1), end=len(tokenized_start2)) + return tokenized, token_span diff --git a/jiant/tasks/lib/templates/mlm.py b/jiant/tasks/lib/templates/mlm.py new file mode 100644 index 000000000..52c14d0f6 --- /dev/null +++ b/jiant/tasks/lib/templates/mlm.py @@ -0,0 +1,187 @@ +import numpy as np +import torch +from dataclasses import dataclass +from typing import List, Tuple + +from jiant.utils.python.datastructures import ReusableGenerator + +from jiant.tasks.core import ( + Task, + TaskTypes, + BaseExample, + BaseTokenizedExample, + BaseDataRow, + BatchMixin, +) +from jiant.tasks.lib.templates.shared import ( + construct_single_input_tokens_and_segment_ids, + create_input_set_from_tokens_and_segments, +) + +NON_MASKED_TOKEN_LABEL_ID = -100 + + +@dataclass +class Example(BaseExample): + guid: str + text: str + + def tokenize(self, tokenizer): + return TokenizedExample(guid=self.guid, input_tokens=tokenizer.tokenize(self.text),) + + +@dataclass +class TokenizedExample(BaseTokenizedExample): + guid: str + input_tokens: List + + def featurize(self, tokenizer, feat_spec): + unpadded_inputs = construct_single_input_tokens_and_segment_ids( + input_tokens=self.input_tokens, tokenizer=tokenizer, feat_spec=feat_spec, + ) + input_set = create_input_set_from_tokens_and_segments( + unpadded_tokens=unpadded_inputs.unpadded_tokens, + unpadded_segment_ids=unpadded_inputs.unpadded_segment_ids, + tokenizer=tokenizer, + feat_spec=feat_spec, + ) + return DataRow( + guid=self.guid, + input_ids=np.array(input_set.input_ids), + input_mask=np.array(input_set.input_mask), + segment_ids=np.array(input_set.segment_ids), + # Masking will be performed on the fly in train + tokens=unpadded_inputs.unpadded_tokens, + ) + + +@dataclass +class DataRow(BaseDataRow): + guid: str + input_ids: np.ndarray + input_mask: np.ndarray + segment_ids: np.ndarray + tokens: list + + +class BaseMLMBatch: + def get_masked(self, mlm_probability, tokenizer, do_mask): + raise NotImplementedError + + +@dataclass +class Batch(BatchMixin, BaseMLMBatch): + input_ids: torch.LongTensor + input_mask: torch.LongTensor + segment_ids: torch.LongTensor + # Only if preset + tokens: list + + def get_masked(self, mlm_probability, tokenizer, do_mask): + if do_mask: + masked_input_ids, masked_lm_labels = mlm_mask_tokens( + inputs=self.input_ids, tokenizer=tokenizer, mlm_probability=mlm_probability, + ) + return MaskedBatch( + masked_input_ids=masked_input_ids, + input_mask=self.input_mask, + segment_ids=self.segment_ids, + masked_lm_labels=masked_lm_labels, + tokens=self.tokens, + ) + else: + # Potentially, the mask_lm_labels should all be -100 + return MaskedBatch( + masked_input_ids=self.input_ids, + input_mask=self.input_mask, + segment_ids=self.segment_ids, + masked_lm_labels=self.input_ids, + tokens=self.tokens, + ) + + +@dataclass +class MaskedBatch(BatchMixin): + masked_input_ids: torch.LongTensor + input_mask: torch.LongTensor + segment_ids: torch.LongTensor + masked_lm_labels: torch.LongTensor + tokens: list + + +class MLMTask(Task): + Example = Example + TokenizedExample = Example + DataRow = DataRow + Batch = Batch + + TASK_TYPE = TaskTypes.MASKED_LANGUAGE_MODELING + + def __init__(self, name, path_dict, mlm_probability=0.15, do_mask=True): + super().__init__(name=name, path_dict=path_dict) + self.mlm_probability = mlm_probability + self.do_mask = do_mask + + def get_train_examples(self): + return self.create_examples(path=self.train_path, set_type="train", return_generator=True) + + def get_val_examples(self): + return self.create_examples(path=self.val_path, set_type="val", return_generator=True) + + def get_test_examples(self): + return self.create_examples(path=self.test_path, set_type="test", return_generator=True) + + @classmethod + def get_examples_generator(cls, path, set_type): + with open(path, "r") as f: + for (i, line) in enumerate(f): + yield Example( + guid="%s-%s" % (set_type, i), text=line.strip(), + ) + + @classmethod + def create_examples(cls, path, set_type, return_generator): + generator = ReusableGenerator(cls.get_examples_generator, path=path, set_type=set_type) + if return_generator: + return generator + else: + return list(generator) + + +def mlm_mask_tokens( + inputs: torch.LongTensor, tokenizer, mlm_probability +) -> Tuple[torch.LongTensor, torch.LongTensor]: + """From HuggingFace""" + device = inputs.device + inputs = inputs.cpu().clone() + labels = inputs.clone() + # We sample a few tokens in each sequence for masked-LM training + # (with probability args.mlm_probability defaults to 0.15 in Bert/RoBERTa) + probability_matrix = torch.full(labels.shape, mlm_probability) + special_tokens_mask = [ + tokenizer.get_special_tokens_mask(val, already_has_special_tokens=True) + for val in labels.tolist() + ] + probability_matrix.masked_fill_(torch.tensor(special_tokens_mask, dtype=torch.bool), value=0.0) + # noinspection PyProtectedMember + if tokenizer._pad_token is not None: + padding_mask = labels.eq(tokenizer.pad_token_id) + probability_matrix.masked_fill_(padding_mask, value=0.0) + masked_indices = torch.bernoulli(probability_matrix).bool() + labels[~masked_indices] = NON_MASKED_TOKEN_LABEL_ID # We only compute loss on masked tokens + + # 80% of the time, we replace masked input tokens with tokenizer.mask_token ([MASK]) + indices_replaced = torch.bernoulli(torch.full(labels.shape, 0.8)).bool() & masked_indices + inputs[indices_replaced] = tokenizer.convert_tokens_to_ids(tokenizer.mask_token) + + # 10% of the time, we replace masked input tokens with random word + indices_random = ( + torch.bernoulli(torch.full(labels.shape, 0.5)).bool() & masked_indices & ~indices_replaced + ) + random_words = torch.randint(len(tokenizer), labels.shape, dtype=torch.long) + inputs[indices_random] = random_words[indices_random] + + # The rest of the time (10% of the time) we keep the masked input tokens unchanged + + # noinspection PyTypeChecker + return inputs.to(device), labels.to(device) diff --git a/jiant/tasks/lib/templates/mlm_premasked.py b/jiant/tasks/lib/templates/mlm_premasked.py new file mode 100644 index 000000000..99eb5d8ab --- /dev/null +++ b/jiant/tasks/lib/templates/mlm_premasked.py @@ -0,0 +1,125 @@ +import numpy as np +import torch +from dataclasses import dataclass +from typing import List + +from jiant.tasks.lib.templates import mlm as mlm_template +from jiant.tasks.core import ( + BaseExample, + BaseTokenizedExample, + BaseDataRow, + BatchMixin, +) +from jiant.tasks.utils import ExclusiveSpan, truncate_sequences +from jiant.tasks.lib.templates.shared import ( + construct_single_input_tokens_and_segment_ids, + create_input_set_from_tokens_and_segments, + pad_single_with_feat_spec, +) + + +@dataclass +class Example(BaseExample): + guid: str + text: str + # Spans over char indices + masked_spans: List[ExclusiveSpan] + + def tokenize(self, tokenizer): + # masked_tokens will be regular tokens except with tokenizer.mask_token for masked spans + # label_tokens will be tokenizer.pad_token except with the regular tokens for masked spans + masked_tokens = [] + label_tokens = [] + curr = 0 + for start, end in self.masked_spans: + # Handle text before next mask + tokenized_text = tokenizer.tokenize(self.text[curr:start]) + masked_tokens += tokenized_text + label_tokens += [tokenizer.pad_token] * len(tokenized_text) + + # Handle mask + tokenized_masked_text = tokenizer.tokenize(self.text[start:end]) + masked_tokens += [tokenizer.mask_token] * len(tokenized_masked_text) + label_tokens += tokenized_masked_text + curr = end + if curr < len(self.text): + tokenized_text = tokenizer.tokenize(self.text[curr:]) + masked_tokens += tokenized_text + label_tokens += [tokenizer.pad_token] * len(tokenized_text) + + return TokenizedExample( + guid=self.guid, masked_tokens=masked_tokens, label_tokens=label_tokens, + ) + + +@dataclass +class TokenizedExample(BaseTokenizedExample): + guid: str + masked_tokens: List + label_tokens: List + + def featurize(self, tokenizer, feat_spec): + # Handle masked_tokens + unpadded_masked_inputs = construct_single_input_tokens_and_segment_ids( + input_tokens=self.masked_tokens, tokenizer=tokenizer, feat_spec=feat_spec, + ) + masked_input_set = create_input_set_from_tokens_and_segments( + unpadded_tokens=unpadded_masked_inputs.unpadded_tokens, + unpadded_segment_ids=unpadded_masked_inputs.unpadded_segment_ids, + tokenizer=tokenizer, + feat_spec=feat_spec, + ) + # Handle label_tokens + special_tokens_count = 2 # CLS, SEP + pad_token = tokenizer.pad_token + (unpadded_label_tokens,) = truncate_sequences( + tokens_ls=[self.label_tokens], + max_length=feat_spec.max_seq_length - special_tokens_count, + ) + if feat_spec.cls_token_at_end: + unpadded_label_tokens = unpadded_label_tokens + [pad_token, pad_token] + else: + unpadded_label_tokens = [pad_token] + unpadded_label_tokens + [pad_token] + unpadded_label_token_ids = tokenizer.convert_tokens_to_ids(unpadded_label_tokens) + masked_lm_labels = pad_single_with_feat_spec( + ls=unpadded_label_token_ids, feat_spec=feat_spec, pad_idx=feat_spec.pad_token_id, + ) + masked_lm_labels = np.array(masked_lm_labels) + masked_lm_labels[ + masked_lm_labels == feat_spec.pad_token_id + ] = mlm_template.NON_MASKED_TOKEN_LABEL_ID + return DataRow( + guid=self.guid, + masked_input_ids=np.array(masked_input_set.input_ids), + input_mask=np.array(masked_input_set.input_mask), + segment_ids=np.array(masked_input_set.segment_ids), + masked_lm_labels=masked_lm_labels, + masked_tokens=unpadded_masked_inputs.unpadded_tokens, + label_tokens=unpadded_label_tokens, + ) + + +@dataclass +class DataRow(BaseDataRow): + guid: str + masked_input_ids: np.ndarray + input_mask: np.ndarray + segment_ids: np.ndarray + masked_lm_labels: np.ndarray + masked_tokens: List + label_tokens: List + + +@dataclass +class Batch(BatchMixin, mlm_template.BaseMLMBatch): + masked_input_ids: torch.LongTensor + input_mask: torch.LongTensor + segment_ids: torch.LongTensor + masked_lm_labels: torch.LongTensor + masked_tokens: List + label_tokens: List + + def get_masked(self, mlm_probability, tokenizer, do_mask): + assert mlm_probability is None + assert not do_mask + return self diff --git a/jiant/tasks/lib/templates/multiple_choice.py b/jiant/tasks/lib/templates/multiple_choice.py new file mode 100644 index 000000000..7324e8933 --- /dev/null +++ b/jiant/tasks/lib/templates/multiple_choice.py @@ -0,0 +1,133 @@ +from abc import ABC + +import numpy as np +import torch +from dataclasses import dataclass +from typing import List + +from jiant.tasks.core import ( + Task, + TaskTypes, + BaseExample, + BaseTokenizedExample, + BaseDataRow, + BatchMixin, +) +from jiant.tasks.lib.templates.shared import ( + create_input_set_from_tokens_and_segments, + add_cls_token, +) +from jiant.tasks.utils import truncate_sequences + + +@dataclass +class Example(BaseExample): + + guid: str + prompt: str + choice_list: List[str] + label: int + + @property + def task(self): + raise NotImplementedError() + + def tokenize(self, tokenizer): + return TokenizedExample( + guid=self.guid, + prompt=tokenizer.tokenize(self.prompt), + choice_list=[tokenizer.tokenize(choice) for choice in self.choice_list], + label_id=self.task.CHOICE_TO_ID[self.label], + ) + + +@dataclass +class TokenizedExample(BaseTokenizedExample): + guid: str + prompt: List + choice_list: List[List] + label_id: int + + def featurize(self, tokenizer, feat_spec): + + if feat_spec.sep_token_extra: + maybe_extra_sep = [tokenizer.sep_token] + maybe_extra_sep_segment_id = [feat_spec.sequence_a_segment_id] + special_tokens_count = 4 # CLS, SEP-SEP, SEP + else: + maybe_extra_sep = [] + maybe_extra_sep_segment_id = [] + special_tokens_count = 3 # CLS, SEP, SEP + + input_set_ls = [] + unpadded_inputs_ls = [] + for choice in self.choice_list: + prompt, choice = truncate_sequences( + tokens_ls=[self.prompt, choice], + max_length=feat_spec.max_seq_length - special_tokens_count, + ) + unpadded_inputs = add_cls_token( + unpadded_tokens=( + # prompt + prompt + + [tokenizer.sep_token] + + maybe_extra_sep + # choice + + choice + + [tokenizer.sep_token] + ), + unpadded_segment_ids=( + # prompt + [feat_spec.sequence_a_segment_id] * (len(prompt) + 1) + + maybe_extra_sep_segment_id + # choice + sep + + [feat_spec.sequence_b_segment_id] * (len(choice) + 1) + ), + tokenizer=tokenizer, + feat_spec=feat_spec, + ) + input_set = create_input_set_from_tokens_and_segments( + unpadded_tokens=unpadded_inputs.unpadded_tokens, + unpadded_segment_ids=unpadded_inputs.unpadded_segment_ids, + tokenizer=tokenizer, + feat_spec=feat_spec, + ) + input_set_ls.append(input_set) + unpadded_inputs_ls.append(unpadded_inputs) + + return DataRow( + guid=self.guid, + input_ids=np.stack([input_set.input_ids for input_set in input_set_ls]), + input_mask=np.stack([input_set.input_mask for input_set in input_set_ls]), + segment_ids=np.stack([input_set.segment_ids for input_set in input_set_ls]), + label_id=self.label_id, + tokens_list=[unpadded_inputs.unpadded_tokens for unpadded_inputs in unpadded_inputs_ls], + ) + + +@dataclass +class DataRow(BaseDataRow): + guid: str + input_ids: np.ndarray # Multiple + input_mask: np.ndarray # Multiple + segment_ids: np.ndarray # Multiple + label_id: int + tokens_list: List[List] # Multiple + + +@dataclass +class Batch(BatchMixin): + input_ids: torch.LongTensor + input_mask: torch.LongTensor + segment_ids: torch.LongTensor + label_id: torch.LongTensor + tokens_list: List + + +class AbstractMultipleChoiceTask(Task, ABC): + + TASK_TYPE = TaskTypes.MULTIPLE_CHOICE + + CHOICE_KEYS = NotImplemented + CHOICE_BIMAP = NotImplemented + NUM_CHOICES = NotImplemented diff --git a/jiant/tasks/lib/templates/shared.py b/jiant/tasks/lib/templates/shared.py new file mode 100644 index 000000000..72078d05c --- /dev/null +++ b/jiant/tasks/lib/templates/shared.py @@ -0,0 +1,345 @@ +import numpy as np +from dataclasses import dataclass +from typing import List, NamedTuple + +from jiant.tasks.core import FeaturizationSpec +from jiant.tasks.utils import truncate_sequences, pad_to_max_seq_length +from jiant.utils.python.datastructures import BiMap + + +class Span(NamedTuple): + start: int + end: int # Use exclusive end, for consistency + + def add(self, i: int): + return Span(start=self.start + i, end=self.end + i) + + def to_slice(self): + return slice(*self) + + def to_array(self): + return np.array([self.start, self.end]) + + +@dataclass +class UnpaddedInputs: + unpadded_tokens: List + unpadded_segment_ids: List + cls_offset: int + + +@dataclass +class InputSet: + input_ids: List + input_mask: List + segment_ids: List + + +def single_sentence_featurize( + guid: str, + input_tokens: List[str], + label_id: int, + tokenizer, + feat_spec: FeaturizationSpec, + data_row_class, +): + unpadded_inputs = construct_single_input_tokens_and_segment_ids( + input_tokens=input_tokens, tokenizer=tokenizer, feat_spec=feat_spec, + ) + return create_generic_data_row_from_tokens_and_segments( + guid=guid, + unpadded_tokens=unpadded_inputs.unpadded_tokens, + unpadded_segment_ids=unpadded_inputs.unpadded_segment_ids, + label_id=label_id, + tokenizer=tokenizer, + feat_spec=feat_spec, + data_row_class=data_row_class, + ) + + +def double_sentence_featurize( + guid: str, + input_tokens_a: List[str], + input_tokens_b: List[str], + label_id: int, + tokenizer, + feat_spec: FeaturizationSpec, + data_row_class, +): + """Featurize an example for a two-input/two-sentence task, and return the example as a DataRow. + + Args: + guid (str): human-readable identifier for interpretability and debugging. + input_tokens_a (List[str]): sequence of tokens in segment a. + input_tokens_b (List[str]): sequence of tokens in segment b. + label_id (int): int representing the label for the task. + tokenizer: + feat_spec (FeaturizationSpec): Tokenization-related metadata. + data_row_class (DataRow): DataRow class used in the task. + + Returns: + DataRow representing an example. + + """ + unpadded_inputs = construct_double_input_tokens_and_segment_ids( + input_tokens_a=input_tokens_a, + input_tokens_b=input_tokens_b, + tokenizer=tokenizer, + feat_spec=feat_spec, + ) + + return create_generic_data_row_from_tokens_and_segments( + guid=guid, + unpadded_tokens=unpadded_inputs.unpadded_tokens, + unpadded_segment_ids=unpadded_inputs.unpadded_segment_ids, + label_id=label_id, + tokenizer=tokenizer, + feat_spec=feat_spec, + data_row_class=data_row_class, + ) + + +def construct_single_input_tokens_and_segment_ids( + input_tokens: List[str], tokenizer, feat_spec: FeaturizationSpec +): + special_tokens_count = 2 # CLS, SEP + + (input_tokens,) = truncate_sequences( + tokens_ls=[input_tokens], max_length=feat_spec.max_seq_length - special_tokens_count, + ) + + return add_cls_token( + unpadded_tokens=input_tokens + [tokenizer.sep_token], + unpadded_segment_ids=( + [feat_spec.sequence_a_segment_id] + + [feat_spec.sequence_a_segment_id] * (len(input_tokens)) + ), + tokenizer=tokenizer, + feat_spec=feat_spec, + ) + + +def construct_double_input_tokens_and_segment_ids( + input_tokens_a: List[str], input_tokens_b: List[str], tokenizer, feat_spec: FeaturizationSpec +): + """Create token and segment id sequences, apply truncation, add separator and class tokens. + + Args: + input_tokens_a (List[str]): sequence of tokens in segment a. + input_tokens_b (List[str]): sequence of tokens in segment b. + tokenizer: + feat_spec (FeaturizationSpec): Tokenization-related metadata. + + Returns: + UnpaddedInputs: unpadded inputs with truncation applied and special tokens appended. + + """ + if feat_spec.sep_token_extra: + maybe_extra_sep = [tokenizer.sep_token] + maybe_extra_sep_segment_id = [feat_spec.sequence_a_segment_id] + special_tokens_count = 4 # CLS, SEP-SEP, SEP + else: + maybe_extra_sep = [] + maybe_extra_sep_segment_id = [] + special_tokens_count = 3 # CLS, SEP, SEP + + input_tokens_a, input_tokens_b = truncate_sequences( + tokens_ls=[input_tokens_a, input_tokens_b], + max_length=feat_spec.max_seq_length - special_tokens_count, + ) + + unpadded_tokens = ( + input_tokens_a + + [tokenizer.sep_token] + + maybe_extra_sep + + input_tokens_b + + [tokenizer.sep_token] + ) + unpadded_segment_ids = ( + [feat_spec.sequence_a_segment_id] * len(input_tokens_a) + + [feat_spec.sequence_a_segment_id] + + maybe_extra_sep_segment_id + + [feat_spec.sequence_b_segment_id] * len(input_tokens_b) + + [feat_spec.sequence_b_segment_id] + ) + return add_cls_token( + unpadded_tokens=unpadded_tokens, + unpadded_segment_ids=unpadded_segment_ids, + tokenizer=tokenizer, + feat_spec=feat_spec, + ) + + +def add_cls_token( + unpadded_tokens: List[str], + unpadded_segment_ids: List[int], + tokenizer, + feat_spec: FeaturizationSpec, +): + """Add class token to unpadded inputs. + + Applies class token to end (or start) of unpadded inputs depending on FeaturizationSpec. + + Args: + unpadded_tokens (List[str]): sequence of unpadded token strings. + unpadded_segment_ids (List[str]): sequence of unpadded segment ids. + tokenizer: + feat_spec (FeaturizationSpec): Tokenization-related metadata. + + Returns: + UnpaddedInputs: unpadded inputs with class token appended. + + """ + if feat_spec.cls_token_at_end: + return UnpaddedInputs( + unpadded_tokens=unpadded_tokens + [tokenizer.cls_token], + unpadded_segment_ids=unpadded_segment_ids + [feat_spec.cls_token_segment_id], + cls_offset=0, + ) + else: + return UnpaddedInputs( + unpadded_tokens=[tokenizer.cls_token] + unpadded_tokens, + unpadded_segment_ids=[feat_spec.cls_token_segment_id] + unpadded_segment_ids, + cls_offset=1, + ) + + +def create_generic_data_row_from_tokens_and_segments( + guid: str, + unpadded_tokens: List[str], + unpadded_segment_ids: List[int], + label_id: int, + tokenizer, + feat_spec: FeaturizationSpec, + data_row_class, +): + """Creates an InputSet and wraps the InputSet into a DataRow class. + + Args: + guid (str): human-readable identifier (for interpretability and debugging). + unpadded_tokens (List[str]): sequence of unpadded token strings. + unpadded_segment_ids (List[int]): sequence of unpadded segment ids. + label_id (int): int representing the label for the task. + tokenizer: + feat_spec (FeaturizationSpec): Tokenization-related metadata. + data_row_class (DataRow): data row class to wrap and return the inputs. + + Returns: + DataRow: data row class containing model inputs. + + """ + input_set = create_input_set_from_tokens_and_segments( + unpadded_tokens=unpadded_tokens, + unpadded_segment_ids=unpadded_segment_ids, + tokenizer=tokenizer, + feat_spec=feat_spec, + ) + return data_row_class( + guid=guid, + input_ids=np.array(input_set.input_ids), + input_mask=np.array(input_set.input_mask), + segment_ids=np.array(input_set.segment_ids), + label_id=label_id, + tokens=unpadded_tokens, + ) + + +def create_input_set_from_tokens_and_segments( + unpadded_tokens: List[str], + unpadded_segment_ids: List[int], + tokenizer, + feat_spec: FeaturizationSpec, +): + """Create padded inputs for model. + + Converts tokens to ids, makes input set (input ids, input mask, and segment ids), adds padding. + + Args: + unpadded_tokens (List[str]): unpadded list of token strings. + unpadded_segment_ids (List[int]): unpadded list of segment ids. + tokenizer: + feat_spec (FeaturizationSpec): Tokenization-related metadata. + + Returns: + Padded input set. + + """ + assert len(unpadded_tokens) == len(unpadded_segment_ids) + input_ids = tokenizer.convert_tokens_to_ids(unpadded_tokens) + input_mask = [1] * len(input_ids) + input_set = pad_features_with_feat_spec( + input_ids=input_ids, + input_mask=input_mask, + unpadded_segment_ids=unpadded_segment_ids, + feat_spec=feat_spec, + ) + return input_set + + +def pad_features_with_feat_spec( + input_ids: List[int], + input_mask: List[int], + unpadded_segment_ids: List[int], + feat_spec: FeaturizationSpec, +): + """Apply padding to feature set according to settings from FeaturizationSpec. + + Args: + input_ids (List[int]): sequence unpadded input ids. + input_mask (List[int]): unpadded input mask sequence. + unpadded_segment_ids (List[int]): sequence of unpadded segment ids. + feat_spec (FeaturizationSpec): Tokenization-related metadata. + + Returns: + InputSet: input set containing padded input ids, input mask, and segment ids. + + """ + return InputSet( + input_ids=pad_single_with_feat_spec( + ls=input_ids, feat_spec=feat_spec, pad_idx=feat_spec.pad_token_id, + ), + input_mask=pad_single_with_feat_spec( + ls=input_mask, feat_spec=feat_spec, pad_idx=feat_spec.pad_token_mask_id, + ), + segment_ids=pad_single_with_feat_spec( + ls=unpadded_segment_ids, feat_spec=feat_spec, pad_idx=feat_spec.pad_token_segment_id, + ), + ) + + +def pad_single_with_feat_spec( + ls: List[int], feat_spec: FeaturizationSpec, pad_idx: int, check=True +): + """Apply padding to sequence according to settings from FeaturizationSpec. + + Args: + ls (List[int]): sequence to pad. + feat_spec (FeaturizationSpec): metadata containing max sequence length and padding settings. + pad_idx (int): element to use for padding. + check (bool): True if padded length should be checked as under the max sequence length. + + Returns: + Sequence with padding applied. + + """ + return pad_to_max_seq_length( + ls=ls, + max_seq_length=feat_spec.max_seq_length, + pad_idx=pad_idx, + pad_right=not feat_spec.pad_on_left, + check=check, + ) + + +def labels_to_bimap(labels): + """Creates mappings from label to id, and from id to label. See details in docs for BiMap. + + Args: + labels: sequence of label to map to ids. + + Returns: + Tuple[Dict, Dict]: mappings from labels to ids, and ids to labels. + + """ + label2id, id2label = BiMap(a=labels, b=list(range(len(labels)))).get_maps() + return label2id, id2label diff --git a/jiant/tasks/lib/templates/span_prediction.py b/jiant/tasks/lib/templates/span_prediction.py new file mode 100644 index 000000000..d9bf13f38 --- /dev/null +++ b/jiant/tasks/lib/templates/span_prediction.py @@ -0,0 +1,175 @@ +from abc import ABC + +import numpy as np +import torch +from dataclasses import dataclass +from typing import List, Tuple + +from jiant.tasks.core import ( + Task, + TaskTypes, + BaseExample, + BaseTokenizedExample, + BaseDataRow, + BatchMixin, +) +from jiant.tasks.lib.templates.shared import ( + create_input_set_from_tokens_and_segments, + add_cls_token, +) +from jiant.tasks.utils import truncate_sequences, pad_to_max_seq_length +from jiant.utils.retokenize import TokenAligner + + +@dataclass +class Example(BaseExample): + + guid: str + passage: str + question: str + answer: str + answer_char_span: (int, int) + + def tokenize(self, tokenizer): + + passage_tokens = tokenizer.tokenize(self.passage) + token_aligner = TokenAligner(source=self.passage, target=passage_tokens) + answer_token_span = token_aligner.project_char_to_token_span( + self.answer_char_span[0], self.answer_char_span[1], inclusive=True + ) + + return TokenizedExample( + guid=self.guid, + passage=passage_tokens, + question=tokenizer.tokenize(self.question), + answer_str=self.answer, + passage_str=self.passage, + answer_token_span=answer_token_span, + token_idx_to_char_idx_map=token_aligner.source_char_idx_to_target_token_idx.T, + ) + + +@dataclass +class TokenizedExample(BaseTokenizedExample): + guid: str + passage: List[str] + question: List[str] + answer_str: str + passage_str: str + answer_token_span: Tuple[int, int] + token_idx_to_char_idx_map: np.ndarray + + def featurize(self, tokenizer, feat_spec): + + if feat_spec.sep_token_extra: + maybe_extra_sep = [tokenizer.sep_token] + maybe_extra_sep_segment_id = [feat_spec.sequence_a_segment_id] + special_tokens_count = 4 # CLS, SEP-SEP, SEP + else: + maybe_extra_sep = [] + maybe_extra_sep_segment_id = [] + special_tokens_count = 3 # CLS, SEP, SEP + + passage, question = truncate_sequences( + tokens_ls=[self.passage, self.question], + max_length=feat_spec.max_seq_length - special_tokens_count, + ) + assert ( + len(passage) >= self.answer_token_span[1] + ), f"Answer span {self.answer_token_span} truncated, please raise max_seq_length." + unpadded_inputs = add_cls_token( + unpadded_tokens=( + passage + [tokenizer.sep_token] + maybe_extra_sep + question + [tokenizer.sep_token] + ), + unpadded_segment_ids=( + [feat_spec.sequence_a_segment_id] * (len(passage) + 1) + + maybe_extra_sep_segment_id + + [feat_spec.sequence_b_segment_id] * (len(question) + 1) + ), + tokenizer=tokenizer, + feat_spec=feat_spec, + ) + gt_span_idxs = list(map(lambda x: x + unpadded_inputs.cls_offset, self.answer_token_span)) + input_set = create_input_set_from_tokens_and_segments( + unpadded_tokens=unpadded_inputs.unpadded_tokens, + unpadded_segment_ids=unpadded_inputs.unpadded_segment_ids, + tokenizer=tokenizer, + feat_spec=feat_spec, + ) + pred_span_mask = pad_to_max_seq_length( + ls=[0] * unpadded_inputs.cls_offset + [1] * len(passage), + max_seq_length=feat_spec.max_seq_length, + pad_idx=0, + pad_right=not feat_spec.pad_on_left, + ) + token_idx_to_char_idx_start = pad_to_max_seq_length( + ls=[-1] * unpadded_inputs.cls_offset + + (self.token_idx_to_char_idx_map > 0).argmax(axis=1).tolist()[: len(passage)], + max_seq_length=feat_spec.max_seq_length, + pad_idx=-1, + pad_right=not feat_spec.pad_on_left, + ) + token_idx_to_char_idx_end = pad_to_max_seq_length( + ls=[-1] * unpadded_inputs.cls_offset + + self.token_idx_to_char_idx_map.cumsum(axis=1).argmax(axis=1).tolist()[: len(passage)], + max_seq_length=feat_spec.max_seq_length, + pad_idx=-1, + pad_right=not feat_spec.pad_on_left, + ) + # When there are multiple greatest elements, argmax will return the index of the first one. + # So, (x > 0).argmax() will return the index of the first non-zero element in an array, + # token_idx_to_char_idx_start is computed in this way to map each token index to the + # beginning char index of that token. On the other side, x.cumsum().argmax() will return + # the index of the last non-zero element in an array, token_idx_to_char_idx_end is + # computed in this way to map each token index to ending char index. + # Once the model predict a span over the token index, these to mapping will help to project + # the span back to char index, and slice the predicted answer string from the input text. + + return DataRow( + guid=self.guid, + input_ids=np.array(input_set.input_ids), + input_mask=np.array(input_set.input_mask), + segment_ids=np.array(input_set.segment_ids), + gt_span_str=self.answer_str, + gt_span_idxs=np.array(gt_span_idxs), + selection_str=self.passage_str, + selection_token_mask=np.array(pred_span_mask), + token_idx_to_char_idx_start=np.array(token_idx_to_char_idx_start), + token_idx_to_char_idx_end=np.array(token_idx_to_char_idx_end), + ) + + +@dataclass +class DataRow(BaseDataRow): + guid: str + input_ids: np.ndarray + input_mask: np.ndarray + segment_ids: np.ndarray + gt_span_str: str + gt_span_idxs: np.ndarray + selection_str: str + selection_token_mask: np.ndarray + token_idx_to_char_idx_start: np.ndarray + token_idx_to_char_idx_end: np.ndarray + + +@dataclass +class Batch(BatchMixin): + guid: List[str] + input_ids: torch.LongTensor + input_mask: torch.LongTensor + segment_ids: torch.LongTensor + gt_span_str: List[str] + gt_span_idxs: torch.LongTensor + selection_str: List[str] + selection_token_mask: torch.LongTensor + token_idx_to_char_idx_start: torch.LongTensor + token_idx_to_char_idx_end: torch.LongTensor + + +class AbstractSpanPredictionTask(Task, ABC): + Example = Example + TokenizedExample = TokenizedExample + DataRow = DataRow + Batch = Batch + TASK_TYPE = TaskTypes.SPAN_PREDICTION diff --git a/jiant/tasks/lib/templates/squad_style/__init__.py b/jiant/tasks/lib/templates/squad_style/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/jiant/tasks/lib/templates/squad_style/core.py b/jiant/tasks/lib/templates/squad_style/core.py new file mode 100644 index 000000000..2c68d72d7 --- /dev/null +++ b/jiant/tasks/lib/templates/squad_style/core.py @@ -0,0 +1,562 @@ +import json +import numpy as np + +import torch +from dataclasses import dataclass +from typing import Union, List, Dict + +from transformers.tokenization_bert import whitespace_tokenize + +from jiant.tasks.lib.templates.squad_style import utils as squad_utils +from jiant.shared.constants import PHASE +from jiant.tasks.core import ( + BaseExample, + BaseDataRow, + BatchMixin, + Task, + TaskTypes, +) +from jiant.utils.python.datastructures import ExtendedDataClassMixin +from jiant.utils.display import maybe_tqdm + +import logging + +logger = logging.getLogger(__name__) + + +@dataclass +class Example(BaseExample): + qas_id: str + question_text: str + context_text: str + answer_text: str + start_position_character: int + title: str + answers: list + is_impossible: bool + + # === + doc_tokens: Union[list, None] = None + char_to_word_offset: Union[list, None] = None + start_position: int = 0 + end_position: int = 0 + + def __post_init__(self): + doc_tokens = [] + char_to_word_offset = [] + prev_is_whitespace = True + + # Split on whitespace so that different tokens may be attributed to their original position. + for c in self.context_text: + if is_whitespace(c): + prev_is_whitespace = True + else: + if prev_is_whitespace: + doc_tokens.append(c) + else: + doc_tokens[-1] += c + prev_is_whitespace = False + char_to_word_offset.append(len(doc_tokens) - 1) + + self.doc_tokens = doc_tokens + self.char_to_word_offset = char_to_word_offset + + # Start end end positions only has a value during evaluation. + if self.start_position_character is not None and not self.is_impossible: + self.start_position = char_to_word_offset[self.start_position_character] + self.end_position = char_to_word_offset[ + min( + self.start_position_character + len(self.answer_text) - 1, + len(char_to_word_offset) - 1, + ) + ] + + def tokenize(self, tokenizer): + raise NotImplementedError("SQuaD is weird") + + def to_feature_list( + self, tokenizer, max_seq_length, doc_stride, max_query_length, set_type, + ): + is_training = set_type == PHASE.TRAIN + features = [] + if is_training and not self.is_impossible: + # Get start and end position + start_position = self.start_position + end_position = self.end_position + + # If the answer cannot be found in the text, then skip this example. + actual_text = " ".join(self.doc_tokens[start_position : (end_position + 1)]) + cleaned_answer_text = " ".join(whitespace_tokenize(self.answer_text)) + if actual_text.find(cleaned_answer_text) == -1: + logger.warning( + "Could not find answer: '%s' vs. '%s'", actual_text, cleaned_answer_text + ) + return [] + + tok_to_orig_index = [] + orig_to_tok_index = [] + all_doc_tokens = [] + for (i, token) in enumerate(self.doc_tokens): + orig_to_tok_index.append(len(all_doc_tokens)) + sub_tokens = tokenizer.tokenize(token) + for sub_token in sub_tokens: + tok_to_orig_index.append(i) + all_doc_tokens.append(sub_token) + + if is_training and not self.is_impossible: + tok_start_position = orig_to_tok_index[self.start_position] + if self.end_position < len(self.doc_tokens) - 1: + tok_end_position = orig_to_tok_index[self.end_position + 1] - 1 + else: + tok_end_position = len(all_doc_tokens) - 1 + + (tok_start_position, tok_end_position) = _improve_answer_span( + all_doc_tokens, tok_start_position, tok_end_position, tokenizer, self.answer_text + ) + + spans = [] + + truncated_query = tokenizer.encode( + self.question_text, + add_special_tokens=False, + truncation=True, + max_length=max_query_length, + ) + sequence_added_tokens = ( + tokenizer.max_len - tokenizer.max_len_single_sentence + 1 + if "roberta" in str(type(tokenizer)) or "camembert" in str(type(tokenizer)) + else tokenizer.max_len - tokenizer.max_len_single_sentence + ) + sequence_pair_added_tokens = tokenizer.max_len - tokenizer.max_len_sentences_pair + + span_doc_tokens = all_doc_tokens + while len(spans) * doc_stride < len(all_doc_tokens): + + encoded_dict = tokenizer.encode_plus( # TODO(thom) update this logic + truncated_query if tokenizer.padding_side == "right" else span_doc_tokens, + span_doc_tokens if tokenizer.padding_side == "right" else truncated_query, + truncation="only_second" if tokenizer.padding_side == "right" else "only_first", + pad_to_max_length=True, + max_length=max_seq_length, + return_overflowing_tokens=True, + stride=max_seq_length + - doc_stride + - len(truncated_query) + - sequence_pair_added_tokens, + return_token_type_ids=True, + ) + + paragraph_len = min( + len(all_doc_tokens) - len(spans) * doc_stride, + max_seq_length - len(truncated_query) - sequence_pair_added_tokens, + ) + + if tokenizer.pad_token_id in encoded_dict["input_ids"]: + if tokenizer.padding_side == "right": + non_padded_ids = encoded_dict["input_ids"][ + : encoded_dict["input_ids"].index(tokenizer.pad_token_id) + ] + else: + last_padding_id_position = ( + len(encoded_dict["input_ids"]) + - 1 + - encoded_dict["input_ids"][::-1].index(tokenizer.pad_token_id) + ) + non_padded_ids = encoded_dict["input_ids"][last_padding_id_position + 1 :] + + else: + non_padded_ids = encoded_dict["input_ids"] + + tokens = tokenizer.convert_ids_to_tokens(non_padded_ids) + + token_to_orig_map = {} + for i in range(paragraph_len): + index = ( + len(truncated_query) + sequence_added_tokens + i + if tokenizer.padding_side == "right" + else i + ) + token_to_orig_map[index] = tok_to_orig_index[len(spans) * doc_stride + i] + + encoded_dict["paragraph_len"] = paragraph_len + encoded_dict["tokens"] = tokens + encoded_dict["token_to_orig_map"] = token_to_orig_map + encoded_dict["truncated_query_with_special_tokens_length"] = ( + len(truncated_query) + sequence_added_tokens + ) + encoded_dict["token_is_max_context"] = {} + encoded_dict["start"] = len(spans) * doc_stride + encoded_dict["length"] = paragraph_len + + spans.append(encoded_dict) + + if "overflowing_tokens" not in encoded_dict or ( + "overflowing_tokens" in encoded_dict + and len(encoded_dict["overflowing_tokens"]) == 0 + ): + break + span_doc_tokens = encoded_dict["overflowing_tokens"] + + for doc_span_index in range(len(spans)): + for j in range(spans[doc_span_index]["paragraph_len"]): + is_max_context = _new_check_is_max_context( + spans, doc_span_index, doc_span_index * doc_stride + j + ) + index = ( + j + if tokenizer.padding_side == "left" + else spans[doc_span_index]["truncated_query_with_special_tokens_length"] + j + ) + spans[doc_span_index]["token_is_max_context"][index] = is_max_context + + for span in spans: + # Identify the position of the CLS token + cls_index = span["input_ids"].index(tokenizer.cls_token_id) + + # p_mask: mask with 1 for token than cannot be in the answer + # (0 for token which can be in an answer) + # Original TF implem also keep the classification token (set to 0) (not sure why...) + p_mask = np.ones_like(span["token_type_ids"]) + if tokenizer.padding_side == "right": + p_mask[len(truncated_query) + sequence_added_tokens :] = 0 + else: + p_mask[-len(span["tokens"]) : -(len(truncated_query) + sequence_added_tokens)] = 0 + + pad_token_indices = np.where(span["input_ids"] == tokenizer.pad_token_id) + special_token_indices = np.asarray( + tokenizer.get_special_tokens_mask( + span["input_ids"], already_has_special_tokens=True + ) + ).nonzero() + + p_mask[pad_token_indices] = 1 + p_mask[special_token_indices] = 1 + + # Set the cls index to 0: the CLS index can be used for impossible answers + p_mask[cls_index] = 0 + + span_is_impossible = self.is_impossible + start_position = 0 + end_position = 0 + if is_training and not span_is_impossible: + # For training, if our document chunk does not contain an annotation + # we throw it out, since there is nothing to predict. + doc_start = span["start"] + doc_end = span["start"] + span["length"] - 1 + out_of_span = False + + # noinspection PyUnboundLocalVariable + if not (tok_start_position >= doc_start and tok_end_position <= doc_end): + out_of_span = True + + if out_of_span: + start_position = cls_index + end_position = cls_index + + # We store "is_impossible" at an example level instead + # noinspection PyUnusedLocal + span_is_impossible = True + else: + if tokenizer.padding_side == "left": + doc_offset = 0 + else: + doc_offset = len(truncated_query) + sequence_added_tokens + + start_position = tok_start_position - doc_start + doc_offset + end_position = tok_end_position - doc_start + doc_offset + + features.append( + DataRow( + unique_id="", + qas_id=self.qas_id, + tokens=span["tokens"], + token_to_orig_map=span["token_to_orig_map"], + token_is_max_context=span["token_is_max_context"], + input_ids=np.array(span["input_ids"]), + input_mask=np.array(span["attention_mask"]), + segment_ids=np.array(span["token_type_ids"]), + cls_index=np.array(cls_index), + p_mask=np.array(p_mask.tolist()), + paragraph_len=span["paragraph_len"], + start_position=start_position, + end_position=end_position, + answers=self.answers, + doc_tokens=self.doc_tokens, + ) + ) + return features + + +@dataclass +class DataRow(BaseDataRow): + unique_id: str + qas_id: str + tokens: list + token_to_orig_map: dict + token_is_max_context: dict + input_ids: np.array + input_mask: np.array + segment_ids: np.array + cls_index: np.array + p_mask: np.array + paragraph_len: int + start_position: int + end_position: int + answers: list + doc_tokens: list + + +@dataclass +class Batch(BatchMixin): + input_ids: torch.LongTensor + input_mask: torch.LongTensor + segment_ids: torch.LongTensor + start_position: torch.LongTensor + end_position: torch.LongTensor + cls_index: torch.LongTensor + p_mask: torch.FloatTensor + tokens: list + + +class BaseSquadStyleTask(Task): + Example = NotImplemented + DataRow = NotImplemented + Batch = NotImplemented + + TASK_TYPE = TaskTypes.SQUAD_STYLE_QA + + def __init__( + self, + name, + path_dict, + version_2_with_negative=False, + n_best_size=20, + max_answer_length=30, + null_score_diff_threshold=0.0, + doc_stride=128, + max_query_length=64, + ): + """SQuAD-style Task object, with support for both SQuAD v1.1 and SQuAD v2.0 formats + + Args: + name (str): task_name + path_dict (Dict[str, str]): Dictionary to paths to data + version_2_with_negative (bool): Whether negative (impossible-to-answer) is an option. + False for SQuAD v1.1-type tasks + True for SquAD 2.0-type tasks + n_best_size (int): The total number of n-best predictions to generate in the + n-best predictions. + max_answer_length (int): The maximum length of an answer that can be generated. + This is needed because the start and end predictions are + not conditioned on one another. + null_score_diff_threshold (float): If null_score - best_non_null is greater than + the threshold predict null. + doc_stride (int): When splitting up a long document into chunks, how much stride + to take between chunks. + max_query_length (int): The maximum number of tokens for the question. Questions + longer than this will be truncated to this length. + """ + super().__init__(name=name, path_dict=path_dict) + self.version_2_with_negative = version_2_with_negative + self.n_best_size = n_best_size + self.max_answer_length = max_answer_length + self.null_score_diff_threshold = null_score_diff_threshold + + # Tokenization hyperparameters + self.doc_stride = doc_stride + self.max_query_length = max_query_length + + def get_train_examples(self): + return self.read_squad_examples(path=self.train_path, set_type=PHASE.TRAIN) + + def get_val_examples(self): + return self.read_squad_examples(path=self.val_path, set_type=PHASE.VAL) + + def get_test_examples(self): + return self.read_squad_examples(path=self.test_path, set_type=PHASE.TEST) + + @classmethod + def read_squad_examples(cls, path, set_type): + return generic_read_squad_examples(path=path, set_type=set_type, example_class=cls.Example,) + + +def generic_read_squad_examples( + path: str, set_type: str, example_class: type = dict, read_title: bool = True +): + + with open(path, "r", encoding="utf-8") as reader: + input_data = json.load(reader)["data"] + + is_training = set_type == PHASE.TRAIN + examples = [] + for entry in maybe_tqdm(input_data, desc="Reading SQuAD Entries"): + if read_title: + title = entry["title"] + else: + title = "-" + for paragraph in entry["paragraphs"]: + context_text = paragraph["context"] + for qa in paragraph["qas"]: + qas_id = qa["id"] + question_text = qa["question"] + start_position_character = None + answer_text = None + answers = [] + + if "is_impossible" in qa: + is_impossible = qa["is_impossible"] + else: + is_impossible = False + + if not is_impossible: + if is_training: + answer = qa["answers"][0] + answer_text = answer["text"] + start_position_character = answer["answer_start"] + else: + answers = qa["answers"] + + example = example_class( + qas_id=qas_id, + question_text=question_text, + context_text=context_text, + answer_text=answer_text, + start_position_character=start_position_character, + title=title, + is_impossible=is_impossible, + answers=answers, + ) + examples.append(example) + return examples + + +@dataclass +class PartialDataRow(ExtendedDataClassMixin): + qas_id: str + doc_tokens: List[str] + tokens: List[str] + token_to_orig_map: Dict[int, int] + token_is_max_context: Dict[int, bool] + doc_tokens: List[str] + answers: List[Dict] + + @classmethod + def from_data_row(cls, data_row: DataRow): + data_row_dict = data_row.to_dict() + return PartialDataRow(**{k: data_row_dict[k] for k in cls.get_fields()}) + + +def data_rows_to_partial_examples( + data_rows: List[PartialDataRow], +) -> List[squad_utils.PartialExample]: + qas_id_to_data_rows = {} + for i, data_row in enumerate(data_rows): + data_row.unique_id = 1000000000 + i + if data_row.qas_id not in qas_id_to_data_rows: + qas_id_to_data_rows[data_row.qas_id] = [] + qas_id_to_data_rows[data_row.qas_id].append(data_row) + partial_examples = [] + for qas_id in sorted(list(qas_id_to_data_rows.keys())): + first_data_row = qas_id_to_data_rows[qas_id][0] + partial_examples.append( + squad_utils.PartialExample( + doc_tokens=first_data_row.doc_tokens, + qas_id=first_data_row.qas_id, + partial_features=[ + squad_utils.PartialFeatures( + unique_id=data_row.unique_id, + tokens=data_row.tokens, + token_to_orig_map=data_row.token_to_orig_map, + token_is_max_context=data_row.token_is_max_context, + ) + for data_row in qas_id_to_data_rows[qas_id] + ], + answers=first_data_row.answers, + ) + ) + return partial_examples + + +def is_whitespace(c_): + if c_ == " " or c_ == "\t" or c_ == "\r" or c_ == "\n" or ord(c_) == 0x202F: + return True + return False + + +def _new_check_is_max_context(doc_spans, cur_span_index, position): + """Check if this is the 'max context' doc span for the token.""" + # if len(doc_spans) == 1: + # return True + best_score = None + best_span_index = None + for (span_index, doc_span) in enumerate(doc_spans): + end = doc_span["start"] + doc_span["length"] - 1 + if position < doc_span["start"]: + continue + if position > end: + continue + num_left_context = position - doc_span["start"] + num_right_context = end - position + score = min(num_left_context, num_right_context) + 0.01 * doc_span["length"] + if best_score is None or score > best_score: + best_score = score + best_span_index = span_index + + return cur_span_index == best_span_index + + +def _improve_answer_span(doc_tokens, input_start, input_end, tokenizer, orig_answer_text): + """Returns tokenized answer spans that better match the annotated answer.""" + tok_answer_text = " ".join(tokenizer.tokenize(orig_answer_text)) + + for new_start in range(input_start, input_end + 1): + for new_end in range(input_end, new_start - 1, -1): + text_span = " ".join(doc_tokens[new_start : (new_end + 1)]) + if text_span == tok_answer_text: + return new_start, new_end + + return input_start, input_end + + +def logits_to_pred_results_list(logits): + """Convert logits to preds + :param logits: np.ndarray (batch_size, 2, seq_len) + :return: List[squad_utils.SquadResult] + """ + return [ + squad_utils.SquadResult( + unique_id=1000000000 + i, start_logits=logits[i, 0], end_logits=logits[i, 1], + ) + for i in range(logits.shape[0]) + ] + + +def compute_predictions_logits_v3( + data_rows: List[Union[PartialDataRow, DataRow]], + logits: np.ndarray, + n_best_size, + max_answer_length, + do_lower_case, + version_2_with_negative, + null_score_diff_threshold, + tokenizer, + skip_get_final_text=False, + verbose=True, +): + """Write final predictions to the json file and log-odds of null if needed.""" + partial_examples = data_rows_to_partial_examples(data_rows) + all_pred_results = logits_to_pred_results_list(logits) + predictions = squad_utils.compute_predictions_logits_v2( + partial_examples=partial_examples, + all_results=all_pred_results, + n_best_size=n_best_size, + max_answer_length=max_answer_length, + do_lower_case=do_lower_case, + version_2_with_negative=version_2_with_negative, + null_score_diff_threshold=null_score_diff_threshold, + tokenizer=tokenizer, + verbose=verbose, + skip_get_final_text=skip_get_final_text, + ) + results = squad_utils.squad_evaluate(partial_examples, predictions) + return results, predictions diff --git a/jiant/tasks/lib/templates/squad_style/utils.py b/jiant/tasks/lib/templates/squad_style/utils.py new file mode 100644 index 000000000..bc84fc9eb --- /dev/null +++ b/jiant/tasks/lib/templates/squad_style/utils.py @@ -0,0 +1,742 @@ +import collections +import math +import re +import string + +from dataclasses import dataclass +from typing import List, Dict + +from transformers.tokenization_bert import BasicTokenizer +from jiant.utils.display import maybe_tqdm + + +@dataclass +class PartialFeatures: + unique_id: int + tokens: List[str] + token_to_orig_map: Dict[int, int] + token_is_max_context: Dict[int, bool] + + +@dataclass +class PartialExample: + doc_tokens: List[str] + qas_id: str + partial_features: List[PartialFeatures] + answers: List[Dict] + + +@dataclass +class SquadResult: + unique_id: int + start_logits: List[float] + end_logits: List[float] + + +def get_partial_examples(examples, features): + example_index_to_features = collections.defaultdict(list) + for feature in features: + example_index_to_features[feature.example_index].append(feature) + partial_examples = [] + for example_index, example in enumerate(examples): + partial_examples.append( + PartialExample( + doc_tokens=example.doc_tokens, + qas_id=example.qas_id, + partial_features=example_index_to_features[example_index], + answers=example.answers, + ) + ) + return partial_examples + + +def compute_predictions_logits_v2( + partial_examples: List[PartialExample], + all_results, + n_best_size, + max_answer_length, + do_lower_case, + version_2_with_negative, + null_score_diff_threshold, + tokenizer, + skip_get_final_text=False, + verbose=True, +): + """Write final predictions to the json file and log-odds of null if needed.""" + unique_id_to_result = {} + for result in all_results: + unique_id_to_result[result.unique_id] = result + + _PrelimPrediction = collections.namedtuple( # pylint: disable=invalid-name + "PrelimPrediction", + ["feature_index", "start_index", "end_index", "start_logit", "end_logit"], + ) + + all_predictions = collections.OrderedDict() + all_nbest_json = collections.OrderedDict() + scores_diff_json = collections.OrderedDict() + + for example in maybe_tqdm(partial_examples, verbose=verbose): + features = example.partial_features + + prelim_predictions = [] + # keep track of the minimum score of null start+end of position 0 + score_null = 1000000 # large and positive + min_null_feature_index = 0 # the paragraph slice with min null score + null_start_logit = 0 # the start logit at the slice with min null score + null_end_logit = 0 # the end logit at the slice with min null score + for (feature_index, feature) in enumerate(features): + result = unique_id_to_result[feature.unique_id] + start_indexes = _get_best_indexes(result.start_logits, n_best_size) + end_indexes = _get_best_indexes(result.end_logits, n_best_size) + # if we could have irrelevant answers, get the min score of irrelevant + if version_2_with_negative: + feature_null_score = result.start_logits[0] + result.end_logits[0] + if feature_null_score < score_null: + score_null = feature_null_score + min_null_feature_index = feature_index + null_start_logit = result.start_logits[0] + null_end_logit = result.end_logits[0] + for start_index in start_indexes: + for end_index in end_indexes: + # We could hypothetically create invalid predictions, e.g., predict + # that the start of the span is in the question. We throw out all + # invalid predictions. + if start_index >= len(feature.tokens): + continue + if end_index >= len(feature.tokens): + continue + if start_index not in feature.token_to_orig_map: + continue + if end_index not in feature.token_to_orig_map: + continue + if not feature.token_is_max_context.get(start_index, False): + continue + if end_index < start_index: + continue + length = end_index - start_index + 1 + if length > max_answer_length: + continue + prelim_predictions.append( + _PrelimPrediction( + feature_index=feature_index, + start_index=start_index, + end_index=end_index, + start_logit=result.start_logits[start_index], + end_logit=result.end_logits[end_index], + ) + ) + if version_2_with_negative: + prelim_predictions.append( + _PrelimPrediction( + feature_index=min_null_feature_index, + start_index=0, + end_index=0, + start_logit=null_start_logit, + end_logit=null_end_logit, + ) + ) + prelim_predictions = sorted( + prelim_predictions, key=lambda x: (x.start_logit + x.end_logit), reverse=True + ) + + _NbestPrediction = collections.namedtuple( # pylint: disable=invalid-name + "NbestPrediction", ["text", "start_logit", "end_logit"] + ) + + seen_predictions = {} + nbest = [] + for pred in prelim_predictions: + if len(nbest) >= n_best_size: + break + feature = features[pred.feature_index] + if pred.start_index > 0: # this is a non-null prediction + tok_tokens = feature.tokens[pred.start_index : (pred.end_index + 1)] + orig_doc_start = feature.token_to_orig_map[pred.start_index] + orig_doc_end = feature.token_to_orig_map[pred.end_index] + orig_tokens = example.doc_tokens[orig_doc_start : (orig_doc_end + 1)] + + tok_text = tokenizer.convert_tokens_to_string(tok_tokens) + + # tok_text = " ".join(tok_tokens) + # + # # De-tokenize WordPieces that have been split off. + # tok_text = tok_text.replace(" ##", "") + # tok_text = tok_text.replace("##", "") + + # Clean whitespace + tok_text = tok_text.strip() + tok_text = " ".join(tok_text.split()) + orig_text = " ".join(orig_tokens) + + if not skip_get_final_text: + final_text = get_final_text(tok_text, orig_text, do_lower_case) + else: + final_text = tok_text + if final_text in seen_predictions: + continue + + seen_predictions[final_text] = True + else: + final_text = "" + seen_predictions[final_text] = True + + nbest.append( + _NbestPrediction( + text=final_text, start_logit=pred.start_logit, end_logit=pred.end_logit + ) + ) + # if we didn't include the empty option in the n-best, include it + if version_2_with_negative: + if "" not in seen_predictions: + nbest.append( + _NbestPrediction( + text="", start_logit=null_start_logit, end_logit=null_end_logit + ) + ) + + # In very rare edge cases we could only have single null prediction. + # So we just create a nonce prediction in this case to avoid failure. + if len(nbest) == 1: + nbest.insert(0, _NbestPrediction(text="empty", start_logit=0.0, end_logit=0.0)) + + # In very rare edge cases we could have no valid predictions. So we + # just create a nonce prediction in this case to avoid failure. + if not nbest: + nbest.append(_NbestPrediction(text="empty", start_logit=0.0, end_logit=0.0)) + + assert len(nbest) >= 1 + + total_scores = [] + best_non_null_entry = None + for entry in nbest: + total_scores.append(entry.start_logit + entry.end_logit) + if not best_non_null_entry: + if entry.text: + best_non_null_entry = entry + + probs = _compute_softmax(total_scores) + + nbest_json = [] + for (i, entry) in enumerate(nbest): + output = collections.OrderedDict() + output["text"] = entry.text + output["probability"] = probs[i] + output["start_logit"] = entry.start_logit + output["end_logit"] = entry.end_logit + nbest_json.append(output) + + assert len(nbest_json) >= 1 + + if not version_2_with_negative: + all_predictions[example.qas_id] = nbest_json[0]["text"] + else: + # predict "" iff the null score - the score of best non-null > threshold + score_diff = ( + score_null - best_non_null_entry.start_logit - best_non_null_entry.end_logit + ) + scores_diff_json[example.qas_id] = score_diff + if score_diff > null_score_diff_threshold: + all_predictions[example.qas_id] = "" + else: + all_predictions[example.qas_id] = best_non_null_entry.text + all_nbest_json[example.qas_id] = nbest_json + + return all_predictions + + +def compute_predictions_logits( + all_examples, + all_features, + all_results, + n_best_size, + max_answer_length, + do_lower_case, + version_2_with_negative, + null_score_diff_threshold, + tokenizer, + skip_get_final_text=False, +): + """Write final predictions to the json file and log-odds of null if needed.""" + example_index_to_features = collections.defaultdict(list) + for feature in all_features: + example_index_to_features[feature.example_index].append(feature) + + unique_id_to_result = {} + for result in all_results: + unique_id_to_result[result.unique_id] = result + + _PrelimPrediction = collections.namedtuple( # pylint: disable=invalid-name + "PrelimPrediction", + ["feature_index", "start_index", "end_index", "start_logit", "end_logit"], + ) + + all_predictions = collections.OrderedDict() + scores_diff_json = collections.OrderedDict() + + for (example_index, example) in enumerate(all_examples): + features = example_index_to_features[example_index] + + prelim_predictions = [] + # keep track of the minimum score of null start+end of position 0 + score_null = 1000000 # large and positive + min_null_feature_index = 0 # the paragraph slice with min null score + null_start_logit = 0 # the start logit at the slice with min null score + null_end_logit = 0 # the end logit at the slice with min null score + for (feature_index, feature) in enumerate(features): + result = unique_id_to_result[feature.unique_id] + start_indexes = _get_best_indexes(result.start_logits, n_best_size) + end_indexes = _get_best_indexes(result.end_logits, n_best_size) + # if we could have irrelevant answers, get the min score of irrelevant + if version_2_with_negative: + feature_null_score = result.start_logits[0] + result.end_logits[0] + if feature_null_score < score_null: + score_null = feature_null_score + min_null_feature_index = feature_index + null_start_logit = result.start_logits[0] + null_end_logit = result.end_logits[0] + for start_index in start_indexes: + for end_index in end_indexes: + # We could hypothetically create invalid predictions, e.g., predict + # that the start of the span is in the question. We throw out all + # invalid predictions. + if start_index >= len(feature.tokens): + continue + if end_index >= len(feature.tokens): + continue + if start_index not in feature.token_to_orig_map: + continue + if end_index not in feature.token_to_orig_map: + continue + if not feature.token_is_max_context.get(start_index, False): + continue + if end_index < start_index: + continue + length = end_index - start_index + 1 + if length > max_answer_length: + continue + prelim_predictions.append( + _PrelimPrediction( + feature_index=feature_index, + start_index=start_index, + end_index=end_index, + start_logit=result.start_logits[start_index], + end_logit=result.end_logits[end_index], + ) + ) + if version_2_with_negative: + prelim_predictions.append( + _PrelimPrediction( + feature_index=min_null_feature_index, + start_index=0, + end_index=0, + start_logit=null_start_logit, + end_logit=null_end_logit, + ) + ) + prelim_predictions = sorted( + prelim_predictions, key=lambda x: (x.start_logit + x.end_logit), reverse=True + ) + + _NbestPrediction = collections.namedtuple( # pylint: disable=invalid-name + "NbestPrediction", ["text", "start_logit", "end_logit"] + ) + + seen_predictions = {} + nbest = [] + for pred in prelim_predictions: + if len(nbest) >= n_best_size: + break + feature = features[pred.feature_index] + if pred.start_index > 0: # this is a non-null prediction + tok_tokens = feature.tokens[pred.start_index : (pred.end_index + 1)] + orig_doc_start = feature.token_to_orig_map[pred.start_index] + orig_doc_end = feature.token_to_orig_map[pred.end_index] + orig_tokens = example.doc_tokens[orig_doc_start : (orig_doc_end + 1)] + + tok_text = tokenizer.convert_tokens_to_string(tok_tokens) + + # tok_text = " ".join(tok_tokens) + # + # # De-tokenize WordPieces that have been split off. + # tok_text = tok_text.replace(" ##", "") + # tok_text = tok_text.replace("##", "") + + # Clean whitespace + tok_text = tok_text.strip() + tok_text = " ".join(tok_text.split()) + orig_text = " ".join(orig_tokens) + + if not skip_get_final_text: + final_text = get_final_text(tok_text, orig_text, do_lower_case) + else: + final_text = tok_text + if final_text in seen_predictions: + continue + + seen_predictions[final_text] = True + else: + final_text = "" + seen_predictions[final_text] = True + + nbest.append( + _NbestPrediction( + text=final_text, start_logit=pred.start_logit, end_logit=pred.end_logit + ) + ) + # if we didn't include the empty option in the n-best, include it + if version_2_with_negative: + if "" not in seen_predictions: + nbest.append( + _NbestPrediction( + text="", start_logit=null_start_logit, end_logit=null_end_logit + ) + ) + + # In very rare edge cases we could only have single null prediction. + # So we just create a nonce prediction in this case to avoid failure. + if len(nbest) == 1: + nbest.insert(0, _NbestPrediction(text="empty", start_logit=0.0, end_logit=0.0)) + + # In very rare edge cases we could have no valid predictions. So we + # just create a nonce prediction in this case to avoid failure. + if not nbest: + nbest.append(_NbestPrediction(text="empty", start_logit=0.0, end_logit=0.0)) + + assert len(nbest) >= 1 + + total_scores = [] + best_non_null_entry = None + for entry in nbest: + total_scores.append(entry.start_logit + entry.end_logit) + if not best_non_null_entry: + if entry.text: + best_non_null_entry = entry + + probs = _compute_softmax(total_scores) + + nbest_json = [] + for (i, entry) in enumerate(nbest): + output = collections.OrderedDict() + output["text"] = entry.text + output["probability"] = probs[i] + output["start_logit"] = entry.start_logit + output["end_logit"] = entry.end_logit + nbest_json.append(output) + + assert len(nbest_json) >= 1 + + if not version_2_with_negative: + all_predictions[example.qas_id] = nbest_json[0]["text"] + else: + # predict "" iff the null score - the score of best non-null > threshold + score_diff = ( + score_null - best_non_null_entry.start_logit - best_non_null_entry.end_logit + ) + scores_diff_json[example.qas_id] = score_diff + if score_diff > null_score_diff_threshold: + all_predictions[example.qas_id] = "" + else: + all_predictions[example.qas_id] = best_non_null_entry.text + + return all_predictions + + +def get_final_text(pred_text, orig_text, do_lower_case): + """Project the tokenized prediction back to the original text.""" + # When we created the data, we kept track of the alignment between original + # (whitespace tokenized) tokens and our WordPiece tokenized tokens. So + # now `orig_text` contains the span of our original text corresponding to the + # span that we predicted. + # + # However, `orig_text` may contain extra characters that we don't want in + # our prediction. + # + # For example, let's say: + # pred_text = steve smith + # orig_text = Steve Smith's + # + # We don't want to return `orig_text` because it contains the extra "'s". + # + # We don't want to return `pred_text` because it's already been normalized + # (the SQuAD eval script also does punctuation stripping/lower casing but + # our tokenizer does additional normalization like stripping accent + # characters). + # + # What we really want to return is "Steve Smith". + # + # Therefore, we have to apply a semi-complicated alignment heuristic between + # `pred_text` and `orig_text` to get a character-to-character alignment. This + # can fail in certain cases in which case we just return `orig_text`. + + def _strip_spaces(text): + ns_chars = [] + ns_to_s_map = collections.OrderedDict() + for idx, c in enumerate(text): + if c == " ": + continue + ns_to_s_map[len(ns_chars)] = idx + ns_chars.append(c) + ns_text = "".join(ns_chars) + return ns_text, ns_to_s_map + + # We first tokenize `orig_text`, strip whitespace from the result + # and `pred_text`, and check if they are the same length. If they are + # NOT the same length, the heuristic has failed. If they are the same + # length, we assume the characters are one-to-one aligned. + tokenizer = BasicTokenizer(do_lower_case=do_lower_case) + + tok_text = " ".join(tokenizer.tokenize(orig_text)) + + start_position = tok_text.find(pred_text) + if start_position == -1: + return orig_text + end_position = start_position + len(pred_text) - 1 + + (orig_ns_text, orig_ns_to_s_map) = _strip_spaces(orig_text) + (tok_ns_text, tok_ns_to_s_map) = _strip_spaces(tok_text) + + if len(orig_ns_text) != len(tok_ns_text): + return orig_text + + # We then project the characters in `pred_text` back to `orig_text` using + # the character-to-character alignment. + tok_s_to_ns_map = {} + for (i, tok_index) in tok_ns_to_s_map.items(): + tok_s_to_ns_map[tok_index] = i + + orig_start_position = None + if start_position in tok_s_to_ns_map: + ns_start_position = tok_s_to_ns_map[start_position] + if ns_start_position in orig_ns_to_s_map: + orig_start_position = orig_ns_to_s_map[ns_start_position] + + if orig_start_position is None: + return orig_text + + orig_end_position = None + if end_position in tok_s_to_ns_map: + ns_end_position = tok_s_to_ns_map[end_position] + if ns_end_position in orig_ns_to_s_map: + orig_end_position = orig_ns_to_s_map[ns_end_position] + + if orig_end_position is None: + return orig_text + + output_text = orig_text[orig_start_position : (orig_end_position + 1)] + return output_text + + +def _get_best_indexes(logits, n_best_size): + """Get the n-best logits from a list.""" + index_and_score = sorted(enumerate(logits), key=lambda x: x[1], reverse=True) + + best_indexes = [] + for i in range(len(index_and_score)): + if i >= n_best_size: + break + best_indexes.append(index_and_score[i][0]) + return best_indexes + + +def _compute_softmax(scores): + """Compute softmax probability over raw logits.""" + if not scores: + return [] + + max_score = None + for score in scores: + if max_score is None or score > max_score: + max_score = score + + exp_scores = [] + total_sum = 0.0 + for score in scores: + x = math.exp(score - max_score) + exp_scores.append(x) + total_sum += x + + probs = [] + for score in exp_scores: + probs.append(score / total_sum) + return probs + + +# === # + + +def squad_evaluate(examples, preds, no_answer_probs=None, no_answer_probability_threshold=1.0): + qas_id_to_has_answer = {example.qas_id: bool(example.answers) for example in examples} + has_answer_qids = [qas_id for qas_id, has_answer in qas_id_to_has_answer.items() if has_answer] + no_answer_qids = [ + qas_id for qas_id, has_answer in qas_id_to_has_answer.items() if not has_answer + ] + + if no_answer_probs is None: + no_answer_probs = {k: 0.0 for k in preds} + + exact, f1 = get_raw_scores(examples, preds) + + exact_threshold = apply_no_ans_threshold( + exact, no_answer_probs, qas_id_to_has_answer, no_answer_probability_threshold + ) + f1_threshold = apply_no_ans_threshold( + f1, no_answer_probs, qas_id_to_has_answer, no_answer_probability_threshold + ) + + evaluation = make_eval_dict(exact_threshold, f1_threshold) + + if has_answer_qids: + has_ans_eval = make_eval_dict(exact_threshold, f1_threshold, qid_list=has_answer_qids) + merge_eval(evaluation, has_ans_eval, "HasAns") + + if no_answer_qids: + no_ans_eval = make_eval_dict(exact_threshold, f1_threshold, qid_list=no_answer_qids) + merge_eval(evaluation, no_ans_eval, "NoAns") + + if no_answer_probs: + find_all_best_thresh(evaluation, preds, exact, f1, no_answer_probs, qas_id_to_has_answer) + + return evaluation + + +def apply_no_ans_threshold(scores, na_probs, qid_to_has_ans, na_prob_thresh): + new_scores = {} + for qid, s in scores.items(): + pred_na = na_probs[qid] > na_prob_thresh + if pred_na: + new_scores[qid] = float(not qid_to_has_ans[qid]) + else: + new_scores[qid] = s + return new_scores + + +def make_eval_dict(exact_scores, f1_scores, qid_list=None): + if not qid_list: + total = len(exact_scores) + return collections.OrderedDict( + [ + ("exact", 100.0 * sum(exact_scores.values()) / total), + ("f1", 100.0 * sum(f1_scores.values()) / total), + ("total", total), + ] + ) + else: + total = len(qid_list) + return collections.OrderedDict( + [ + ("exact", 100.0 * sum(exact_scores[k] for k in qid_list) / total), + ("f1", 100.0 * sum(f1_scores[k] for k in qid_list) / total), + ("total", total), + ] + ) + + +def merge_eval(main_eval, new_eval, prefix): + for k in new_eval: + main_eval["%s_%s" % (prefix, k)] = new_eval[k] + + +def find_all_best_thresh(main_eval, preds, exact_raw, f1_raw, na_probs, qid_to_has_ans): + best_exact, exact_thresh = find_best_thresh(preds, exact_raw, na_probs, qid_to_has_ans) + best_f1, f1_thresh = find_best_thresh(preds, f1_raw, na_probs, qid_to_has_ans) + + main_eval["best_exact"] = best_exact + main_eval["best_exact_thresh"] = exact_thresh + main_eval["best_f1"] = best_f1 + main_eval["best_f1_thresh"] = f1_thresh + + +def find_best_thresh(preds, scores, na_probs, qid_to_has_ans): + num_no_ans = sum(1 for k in qid_to_has_ans if not qid_to_has_ans[k]) + cur_score = num_no_ans + best_score = cur_score + best_thresh = 0.0 + qid_list = sorted(na_probs, key=lambda k: na_probs[k]) + for _, qid in enumerate(qid_list): + if qid not in scores: + continue + if qid_to_has_ans[qid]: + diff = scores[qid] + else: + if preds[qid]: + diff = -1 + else: + diff = 0 + cur_score += diff + if cur_score > best_score: + best_score = cur_score + best_thresh = na_probs[qid] + return 100.0 * best_score / len(scores), best_thresh + + +def get_raw_scores(examples, preds): + """Computes the exact and f1 scores from the examples and the model predictions""" + exact_scores = {} + f1_scores = {} + + for example in examples: + qas_id = example.qas_id + gold_answers = [ + answer["text"] for answer in example.answers if normalize_answer(answer["text"]) + ] + + if not gold_answers: + # For unanswerable questions, only correct answer is empty string + gold_answers = [""] + + if qas_id not in preds: + print("Missing prediction for %s" % qas_id) + continue + + prediction = preds[qas_id] + exact_scores[qas_id] = max(compute_exact(a, prediction) for a in gold_answers) + f1_scores[qas_id] = max(compute_f1(a, prediction) for a in gold_answers) + + return exact_scores, f1_scores + + +def normalize_answer(s): + """Lower text and remove punctuation, articles and extra whitespace.""" + + def remove_articles(text): + regex = re.compile(r"\b(a|an|the)\b", re.UNICODE) + return re.sub(regex, " ", text) + + def white_space_fix(text): + return " ".join(text.split()) + + def remove_punc(text): + exclude = set(string.punctuation) + return "".join(ch for ch in text if ch not in exclude) + + def lower(text): + return text.lower() + + return white_space_fix(remove_articles(remove_punc(lower(s)))) + + +def get_tokens(s): + if not s: + return [] + return normalize_answer(s).split() + + +def compute_exact(a_gold, a_pred): + return int(normalize_answer(a_gold) == normalize_answer(a_pred)) + + +def compute_f1(a_gold, a_pred): + gold_toks = get_tokens(a_gold) + pred_toks = get_tokens(a_pred) + common = collections.Counter(gold_toks) & collections.Counter(pred_toks) + num_same = sum(common.values()) + if len(gold_toks) == 0 or len(pred_toks) == 0: + # If either is no-answer, then F1 is 1 if they agree, 0 otherwise + return int(gold_toks == pred_toks) + if num_same == 0: + return 0 + precision = 1.0 * num_same / len(pred_toks) + recall = 1.0 * num_same / len(gold_toks) + f1 = (2 * precision * recall) / (precision + recall) + return f1 diff --git a/jiant/tasks/lib/tydiqa.py b/jiant/tasks/lib/tydiqa.py new file mode 100644 index 000000000..0004207e0 --- /dev/null +++ b/jiant/tasks/lib/tydiqa.py @@ -0,0 +1,57 @@ +from dataclasses import dataclass + +from jiant.tasks.lib.templates.squad_style import core as squad_style_template + + +@dataclass +class Example(squad_style_template.Example): + def tokenize(self, tokenizer): + raise NotImplementedError("SQuaD is weird") + + +@dataclass +class DataRow(squad_style_template.DataRow): + pass + + +@dataclass +class Batch(squad_style_template.Batch): + pass + + +class TyDiQATask(squad_style_template.BaseSquadStyleTask): + Example = Example + DataRow = DataRow + Batch = Batch + + def __init__( + self, + name, + path_dict, + language, + version_2_with_negative=False, + n_best_size=20, + max_answer_length=30, + null_score_diff_threshold=0.0, + ): + super().__init__( + name=name, + path_dict=path_dict, + version_2_with_negative=version_2_with_negative, + n_best_size=n_best_size, + max_answer_length=max_answer_length, + null_score_diff_threshold=null_score_diff_threshold, + ) + self.language = language + + def get_train_examples(self): + if self.language == "en": + return self.read_squad_examples(path=self.train_path, set_type="train") + else: + raise NotImplementedError("TyDiQA does not have training examples except for English") + + @classmethod + def read_squad_examples(cls, path, set_type): + return squad_style_template.generic_read_squad_examples( + path=path, set_type=set_type, example_class=cls.Example, + ) diff --git a/jiant/tasks/lib/udpos.py b/jiant/tasks/lib/udpos.py new file mode 100644 index 000000000..6a0a052f2 --- /dev/null +++ b/jiant/tasks/lib/udpos.py @@ -0,0 +1,206 @@ +import numpy as np +import torch +from dataclasses import dataclass +from typing import List, Union + +from jiant.tasks.core import ( + BaseExample, + BaseTokenizedExample, + BaseDataRow, + BatchMixin, + Task, + TaskTypes, +) +from jiant.tasks.lib.templates.shared import ( + labels_to_bimap, + create_input_set_from_tokens_and_segments, + construct_single_input_tokens_and_segment_ids, + pad_single_with_feat_spec, +) +from jiant.utils.python.datastructures import zip_equal +from jiant.utils.python.io import read_file_lines + +ARBITRARY_OVERLY_LONG_WORD_CONSTRAINT = 100 +# In a rare number of cases, a single word (usually something like a mis-processed URL) +# is overly long, and should not be treated as a real multi-subword-token word. +# In these cases, we simply replace it with an UNK token. + + +@dataclass +class Example(BaseExample): + guid: str + tokens: List[str] + pos_list: List[str] + + def tokenize(self, tokenizer): + all_tokenized_tokens = [] + labels = [] + label_mask = [] + for token, pos in zip_equal(self.tokens, self.pos_list): + # Tokenize each "token" separately, assign label only to first token + tokenized = tokenizer.tokenize(token) + # If the token can't be tokenized, or is too long, replace with a single + if len(tokenized) == 0 or len(tokenized) > ARBITRARY_OVERLY_LONG_WORD_CONSTRAINT: + tokenized = [tokenizer.unk_token] + all_tokenized_tokens += tokenized + padding_length = len(tokenized) - 1 + labels += [UdposTask.LABEL_TO_ID.get(pos, None)] + [None] * padding_length + label_mask += [1] + [0] * padding_length + + return TokenizedExample( + guid=self.guid, tokens=all_tokenized_tokens, labels=labels, label_mask=label_mask, + ) + + +@dataclass +class TokenizedExample(BaseTokenizedExample): + guid: str + tokens: List + labels: List[Union[int, None]] + label_mask: List[int] + + def featurize(self, tokenizer, feat_spec): + unpadded_inputs = construct_single_input_tokens_and_segment_ids( + input_tokens=self.tokens, tokenizer=tokenizer, feat_spec=feat_spec, + ) + input_set = create_input_set_from_tokens_and_segments( + unpadded_tokens=unpadded_inputs.unpadded_tokens, + unpadded_segment_ids=unpadded_inputs.unpadded_segment_ids, + tokenizer=tokenizer, + feat_spec=feat_spec, + ) + + # Replicate padding / additional tokens for the label ids and mask + if feat_spec.sep_token_extra: + label_suffix = [None, None] + mask_suffix = [0, 0] + special_tokens_count = 3 # CLS, SEP-SEP + else: + label_suffix = [None] + mask_suffix = [0] + special_tokens_count = 2 # CLS, SEP + unpadded_labels = ( + [None] + self.labels[: feat_spec.max_seq_length - special_tokens_count] + label_suffix + ) + unpadded_labels = [i if i is not None else -1 for i in unpadded_labels] + unpadded_label_mask = ( + [0] + self.label_mask[: feat_spec.max_seq_length - special_tokens_count] + mask_suffix + ) + + padded_labels = pad_single_with_feat_spec( + ls=unpadded_labels, feat_spec=feat_spec, pad_idx=-1, + ) + padded_label_mask = pad_single_with_feat_spec( + ls=unpadded_label_mask, feat_spec=feat_spec, pad_idx=0, + ) + + return DataRow( + guid=self.guid, + input_ids=np.array(input_set.input_ids), + input_mask=np.array(input_set.input_mask), + segment_ids=np.array(input_set.segment_ids), + label_ids=np.array(padded_labels), + label_mask=np.array(padded_label_mask), + tokens=unpadded_inputs.unpadded_tokens, + ) + + +@dataclass +class DataRow(BaseDataRow): + guid: str + input_ids: np.ndarray + input_mask: np.ndarray + segment_ids: np.ndarray + label_ids: np.ndarray + label_mask: np.ndarray + tokens: list + + +@dataclass +class Batch(BatchMixin): + input_ids: torch.LongTensor + input_mask: torch.LongTensor + segment_ids: torch.LongTensor + label_ids: torch.LongTensor + label_mask: torch.LongTensor + tokens: list + + +class UdposTask(Task): + + Example = Example + TokenizedExample = Example + DataRow = DataRow + Batch = Batch + + TASK_TYPE = TaskTypes.TAGGING + LABELS = [ + "ADJ", + "ADP", + "ADV", + "AUX", + "CCONJ", + "DET", + "INTJ", + "NOUN", + "NUM", + "PART", + "PRON", + "PROPN", + "PUNCT", + "SCONJ", + "SYM", + "VERB", + "X", + ] + LABEL_TO_ID, ID_TO_LABEL = labels_to_bimap(LABELS) + + def __init__(self, name, path_dict, language): + super().__init__(name=name, path_dict=path_dict) + self.language = language + + @property + def num_labels(self): + return len(self.LABELS) + + def get_train_examples(self): + return self._create_examples(data_path=self.path_dict["train"], set_type="train") + + def get_val_examples(self): + return self._create_examples(data_path=self.path_dict["val"], set_type="val") + + def get_test_examples(self): + return self._create_examples(data_path=self.path_dict["test"], set_type="test") + + @classmethod + def _create_examples(cls, data_path, set_type): + curr_token_list, curr_pos_list = [], [] + data_lines = read_file_lines(data_path, "r", encoding="utf-8") + examples = [] + idx = 0 + for data_line in data_lines: + data_line = data_line.strip() + if data_line: + if set_type == "test": + line_tokens = data_line.split("\t") + if len(line_tokens) == 2: + token, pos = line_tokens + else: + token, pos = data_line, None + else: + token, pos = data_line.split("\t") + curr_token_list.append(token) + curr_pos_list.append(pos) + else: + examples.append( + Example( + guid=f"{set_type}-{idx}", tokens=curr_token_list, pos_list=curr_pos_list, + ) + ) + idx += 1 + curr_token_list, curr_pos_list = [], [] + if curr_token_list: + examples.append( + Example(guid=f"{set_type}-{idx}", tokens=curr_token_list, pos_list=curr_pos_list) + ) + return examples diff --git a/jiant/tasks/lib/wic.py b/jiant/tasks/lib/wic.py new file mode 100644 index 000000000..5bc0f58f3 --- /dev/null +++ b/jiant/tasks/lib/wic.py @@ -0,0 +1,270 @@ +import numpy as np +import torch +from dataclasses import dataclass +from typing import List +import string + +from jiant.tasks.core import ( + BaseExample, + BaseTokenizedExample, + BaseDataRow, + BatchMixin, + SuperGlueMixin, + Task, + TaskTypes, +) +from jiant.tasks.lib.templates.shared import ( + labels_to_bimap, + add_cls_token, + create_input_set_from_tokens_and_segments, +) +from jiant.tasks.utils import truncate_sequences, ExclusiveSpan +from jiant.utils.python.io import read_json_lines +from jiant.utils import retokenize +from jiant.utils.tokenization_normalization import normalize_tokenizations + + +@dataclass +class Example(BaseExample): + guid: str + sentence1: str + sentence2: str + word: str + span1: ExclusiveSpan + span2: ExclusiveSpan + label: str + + def tokenize(self, tokenizer): + def tokenize_span(tokenizer, sentence: str, char_span: ExclusiveSpan): + """Tokenizes sentence and projects char_span to token span. + + Args: + tokenizer (transformers.PreTrainedTokenizer): Tokenizer used + sentence (str): Sentence to be tokenized + char_span (ExclusiveSpan): character indexed span for sentence + + Returns: + sentence_target_tokenization (List[str]): tokenized sentence + target_span (ExclusiveSpane): token span for sentence + """ + span_start_idx = len(sentence[: char_span.start].split()) + # If the first word in a span starts with punctuation, the first word will + # erroneously be split into two strings by .split(). + # ie: 'takeaway' -> ["'", "takeaway"] + # For span alignment, we start the list index at the punctuation. + if (span_start_idx != 0) and (sentence[: (char_span.start)][-1] in string.punctuation): + span_start_idx = span_start_idx - 1 + span_text = sentence[char_span.start : char_span.end] + + sentence_space_tokenization = sentence.split() + sentence_target_tokenization = tokenizer.tokenize(sentence) + ( + sentence_normed_space_tokenization, + sentence_normed_target_tokenization, + ) = normalize_tokenizations( + sentence_space_tokenization, sentence_target_tokenization, tokenizer + ) + span_start_char = len(" ".join(sentence_normed_space_tokenization[:span_start_idx])) + span_text_char = len(span_text) + aligner = retokenize.TokenAligner( + sentence_normed_space_tokenization, sentence_normed_target_tokenization + ) + target_span = ExclusiveSpan( + *aligner.project_char_to_token_span( + span_start_char, span_start_char + span_text_char + ) + ) + return sentence_target_tokenization, target_span + + sentence1_target_tokenization, target_span1 = tokenize_span( + tokenizer, self.sentence1, self.span1 + ) + sentence2_target_tokenization, target_span2 = tokenize_span( + tokenizer, self.sentence2, self.span2 + ) + + return TokenizedExample( + guid=self.guid, + sentence1_tokens=sentence1_target_tokenization, + sentence2_tokens=sentence2_target_tokenization, + word=tokenizer.tokenize(self.word), # might be more than one token + sentence1_span=target_span1, + sentence2_span=target_span2, + label_id=WiCTask.LABEL_TO_ID[self.label], + ) + + +@dataclass +class TokenizedExample(BaseTokenizedExample): + guid: str + sentence1_tokens: List[str] + sentence2_tokens: List[str] + word: List[str] + sentence1_span: ExclusiveSpan + sentence2_span: ExclusiveSpan + label_id: int + + def featurize(self, tokenizer, feat_spec): + if feat_spec.sep_token_extra: + maybe_extra_sep = [tokenizer.sep_token] + maybe_extra_sep_segment_id = [feat_spec.sequence_a_segment_id] + special_tokens_count = 6 # CLS, SEP-SEP, SEP-SEP, SEP + else: + maybe_extra_sep = [] + maybe_extra_sep_segment_id = [] + special_tokens_count = 4 # CLS, SEP, SEP, SEP + + sentence1_tokens, sentence2_tokens = truncate_sequences( + tokens_ls=[self.sentence1_tokens, self.sentence2_tokens], + max_length=feat_spec.max_seq_length - len(self.word) - special_tokens_count, + ) + + unpadded_tokens = ( + self.word + + [tokenizer.sep_token] + + maybe_extra_sep + + sentence1_tokens + + [tokenizer.sep_token] + + maybe_extra_sep + + sentence2_tokens + + [tokenizer.sep_token] + ) + # Don't have a choice here -- just leave words as part of sent1 + unpadded_segment_ids = ( + [feat_spec.sequence_a_segment_id] * (len(self.word) + 1) + + maybe_extra_sep_segment_id + + [feat_spec.sequence_a_segment_id] * (len(sentence1_tokens) + 1) + + maybe_extra_sep_segment_id + + [feat_spec.sequence_b_segment_id] * (len(sentence2_tokens) + 1) + ) + + unpadded_inputs = add_cls_token( + unpadded_tokens=unpadded_tokens, + unpadded_segment_ids=unpadded_segment_ids, + tokenizer=tokenizer, + feat_spec=feat_spec, + ) + + input_set = create_input_set_from_tokens_and_segments( + unpadded_tokens=unpadded_inputs.unpadded_tokens, + unpadded_segment_ids=unpadded_inputs.unpadded_segment_ids, + tokenizer=tokenizer, + feat_spec=feat_spec, + ) + + word_sep_offset = 2 if feat_spec.sep_token_extra else 1 + sent1_sep_offset = 2 if feat_spec.sep_token_extra else 1 + + # Both should be inclusive spans at the end + sentence1_span = ExclusiveSpan( + start=self.sentence1_span[0] + + unpadded_inputs.cls_offset + + word_sep_offset + + len(self.word), + end=self.sentence1_span[1] + + unpadded_inputs.cls_offset + + word_sep_offset + + len(self.word), + ).to_inclusive() + sentence2_span = ExclusiveSpan( + start=self.sentence2_span[0] + + unpadded_inputs.cls_offset + + word_sep_offset + + sent1_sep_offset + + len(self.word) + + len(sentence1_tokens), + end=self.sentence2_span[1] + + unpadded_inputs.cls_offset + + word_sep_offset + + sent1_sep_offset + + len(self.word) + + len(sentence1_tokens), + ).to_inclusive() + + return DataRow( + guid=self.guid, + input_ids=np.array(input_set.input_ids), + input_mask=np.array(input_set.input_mask), + segment_ids=np.array(input_set.segment_ids), + spans=np.array([sentence1_span, sentence2_span]), + label_id=self.label_id, + tokens=unpadded_inputs.unpadded_tokens, + word=self.word, + ) + + +@dataclass +class DataRow(BaseDataRow): + guid: str + input_ids: np.array + input_mask: np.array + segment_ids: np.array + spans: np.array # num_spans x 2 + label_id: int + tokens: List + word: List + + +@dataclass +class Batch(BatchMixin): + input_ids: torch.LongTensor + input_mask: torch.LongTensor + segment_ids: torch.LongTensor + spans: torch.LongTensor + label_id: torch.LongTensor + tokens: List + word: List + + +class WiCTask(SuperGlueMixin, Task): + Example = Example + TokenizedExample = Example + DataRow = DataRow + Batch = Batch + + TASK_TYPE = TaskTypes.SPAN_COMPARISON_CLASSIFICATION + LABELS = [False, True] + LABEL_TO_ID, ID_TO_LABEL = labels_to_bimap(LABELS) + + @property + def num_spans(self): + return 2 + + def get_train_examples(self): + return self._create_examples(lines=read_json_lines(self.train_path), set_type="train") + + def get_val_examples(self): + return self._create_examples(lines=read_json_lines(self.val_path), set_type="val") + + def get_test_examples(self): + return self._create_examples(lines=read_json_lines(self.test_path), set_type="test") + + @classmethod + def _create_examples(cls, lines, set_type): + examples = [] + for line in lines: + span1 = ExclusiveSpan(int(line["start1"]), int(line["end1"])) + span2 = ExclusiveSpan(int(line["start2"]), int(line["end2"])) + # Note, the chosen word may be different (e.g. different tenses) in sent1 and sent2, + # hence we don't do an assert here. + examples.append( + Example( + # NOTE: WiCTask.super_glue_format_preds() is dependent on this guid format. + guid="%s-%s" % (set_type, line["idx"]), + sentence1=line["sentence1"], + sentence2=line["sentence2"], + word=line["word"], + span1=span1, + span2=span2, + label=line["label"] if set_type != "test" else cls.LABELS[-1], + ) + ) + return examples + + @classmethod + def super_glue_format_preds(cls, pred_dict): + """Reformat this task's raw predictions to have the structure expected by SuperGLUE.""" + lines = [] + for pred, guid in zip(list(pred_dict["preds"]), list(pred_dict["guids"])): + lines.append({"idx": int(guid.split("-")[1]), "label": str(cls.LABELS[pred]).lower()}) + return lines diff --git a/jiant/tasks/lib/wnli.py b/jiant/tasks/lib/wnli.py new file mode 100644 index 000000000..790cd9c5d --- /dev/null +++ b/jiant/tasks/lib/wnli.py @@ -0,0 +1,105 @@ +import numpy as np +import torch +from dataclasses import dataclass +from typing import List + +from jiant.tasks.core import ( + BaseExample, + BaseTokenizedExample, + BaseDataRow, + BatchMixin, + GlueMixin, + Task, + TaskTypes, +) +from jiant.tasks.lib.templates.shared import double_sentence_featurize, labels_to_bimap +from jiant.utils.python.io import read_jsonl + + +@dataclass +class Example(BaseExample): + guid: str + input_premise: str + input_hypothesis: str + label: str + + def tokenize(self, tokenizer): + return TokenizedExample( + guid=self.guid, + input_premise=tokenizer.tokenize(self.input_premise), + input_hypothesis=tokenizer.tokenize(self.input_hypothesis), + label_id=WnliTask.LABEL_TO_ID[self.label], + ) + + +@dataclass +class TokenizedExample(BaseTokenizedExample): + guid: str + input_premise: List + input_hypothesis: List + label_id: int + + def featurize(self, tokenizer, feat_spec): + return double_sentence_featurize( + guid=self.guid, + input_tokens_a=self.input_premise, + input_tokens_b=self.input_hypothesis, + label_id=self.label_id, + tokenizer=tokenizer, + feat_spec=feat_spec, + data_row_class=DataRow, + ) + + +@dataclass +class DataRow(BaseDataRow): + guid: str + input_ids: np.ndarray + input_mask: np.ndarray + segment_ids: np.ndarray + label_id: int + tokens: list + + +@dataclass +class Batch(BatchMixin): + input_ids: torch.LongTensor + input_mask: torch.LongTensor + segment_ids: torch.LongTensor + label_id: torch.LongTensor + tokens: list + + +class WnliTask(GlueMixin, Task): + Example = Example + TokenizedExample = Example + DataRow = DataRow + Batch = Batch + + TASK_TYPE = TaskTypes.CLASSIFICATION + LABELS = ["0", "1"] + LABEL_TO_ID, ID_TO_LABEL = labels_to_bimap(LABELS) + + def get_train_examples(self): + return self._create_examples(lines=read_jsonl(self.train_path), set_type="train") + + def get_val_examples(self): + return self._create_examples(lines=read_jsonl(self.val_path), set_type="val") + + def get_test_examples(self): + return self._create_examples(lines=read_jsonl(self.test_path), set_type="test") + + @classmethod + def _create_examples(cls, lines, set_type): + examples = [] + for (i, line) in enumerate(lines): + examples.append( + Example( + # NOTE: get_glue_preds() is dependent on this guid format. + guid="%s-%s" % (set_type, i), + input_premise=line["premise"], + input_hypothesis=line["hypothesis"], + label=line["label"] if set_type != "test" else cls.LABELS[-1], + ) + ) + return examples diff --git a/jiant/tasks/lib/wsc.py b/jiant/tasks/lib/wsc.py new file mode 100644 index 000000000..300556dcc --- /dev/null +++ b/jiant/tasks/lib/wsc.py @@ -0,0 +1,205 @@ +import numpy as np +import torch +from dataclasses import dataclass +from typing import List + +from jiant.tasks.core import ( + BaseExample, + BaseTokenizedExample, + BaseDataRow, + BatchMixin, + SuperGlueMixin, + Task, + TaskTypes, +) +from jiant.tasks.lib.templates.shared import ( + labels_to_bimap, + add_cls_token, + create_input_set_from_tokens_and_segments, +) +from jiant.tasks.utils import truncate_sequences, ExclusiveSpan +from jiant.utils import retokenize +from jiant.utils.python.io import read_json_lines +from jiant.utils.tokenization_normalization import normalize_tokenizations + + +@dataclass +class Example(BaseExample): + guid: str + text: str + span1_idx: int + span2_idx: int + span1_text: str + span2_text: str + label: str + + def tokenize(self, tokenizer): + space_tokenization = self.text.split() + target_tokenization = tokenizer.tokenize(self.text) + normed_space_tokenization, normed_target_tokenization = normalize_tokenizations( + space_tokenization, target_tokenization, tokenizer + ) + aligner = retokenize.TokenAligner(normed_space_tokenization, normed_target_tokenization) + span1_token_count = len(self.span1_text.split()) + span2_token_count = len(self.span2_text.split()) + target_span1 = ExclusiveSpan( + *aligner.project_token_span(self.span1_idx, self.span1_idx + span1_token_count) + ) + target_span2 = ExclusiveSpan( + *aligner.project_token_span(self.span2_idx, self.span2_idx + span2_token_count) + ) + return TokenizedExample( + guid=self.guid, + tokens=target_tokenization, + span1_span=target_span1, + span2_span=target_span2, + span1_text=self.span1_text, + span2_text=self.span2_text, + label_id=WSCTask.LABEL_TO_ID[self.label], + ) + + +@dataclass +class TokenizedExample(BaseTokenizedExample): + guid: str + tokens: List + span1_span: ExclusiveSpan + span2_span: ExclusiveSpan + span1_text: str + span2_text: str + label_id: int + + def featurize(self, tokenizer, feat_spec): + special_tokens_count = 2 # CLS, SEP + + (tokens,) = truncate_sequences( + tokens_ls=[self.tokens], max_length=feat_spec.max_seq_length - special_tokens_count, + ) + + unpadded_tokens = tokens + [tokenizer.sep_token] + unpadded_segment_ids = [feat_spec.sequence_a_segment_id] * (len(self.tokens) + 1) + + unpadded_inputs = add_cls_token( + unpadded_tokens=unpadded_tokens, + unpadded_segment_ids=unpadded_segment_ids, + tokenizer=tokenizer, + feat_spec=feat_spec, + ) + + input_set = create_input_set_from_tokens_and_segments( + unpadded_tokens=unpadded_inputs.unpadded_tokens, + unpadded_segment_ids=unpadded_inputs.unpadded_segment_ids, + tokenizer=tokenizer, + feat_spec=feat_spec, + ) + span1_span = ExclusiveSpan( + start=self.span1_span[0] + unpadded_inputs.cls_offset, + end=self.span1_span[1] + unpadded_inputs.cls_offset, + ).to_inclusive() + span2_span = ExclusiveSpan( + start=self.span2_span[0] + unpadded_inputs.cls_offset, + end=self.span2_span[1] + unpadded_inputs.cls_offset, + ).to_inclusive() + + return DataRow( + guid=self.guid, + input_ids=np.array(input_set.input_ids), + input_mask=np.array(input_set.input_mask), + segment_ids=np.array(input_set.segment_ids), + spans=np.array([span1_span, span2_span]), + label_id=self.label_id, + tokens=unpadded_inputs.unpadded_tokens, + span1_text=self.span1_text, + span2_text=self.span2_text, + ) + + +@dataclass +class DataRow(BaseDataRow): + guid: str + input_ids: np.ndarray + input_mask: np.ndarray + segment_ids: np.ndarray + spans: np.ndarray + label_id: int + tokens: List + span1_text: str + span2_text: str + + def get_tokens(self): + return [self.tokens] + + +@dataclass +class Batch(BatchMixin): + input_ids: torch.LongTensor + input_mask: torch.LongTensor + segment_ids: torch.LongTensor + spans: torch.LongTensor + label_id: torch.LongTensor + tokens: List + span1_text: List + span2_text: List + + +class WSCTask(SuperGlueMixin, Task): + Example = Example + TokenizedExample = Example + DataRow = DataRow + Batch = Batch + + TASK_TYPE = TaskTypes.SPAN_COMPARISON_CLASSIFICATION + LABELS = [False, True] + LABEL_TO_ID, ID_TO_LABEL = labels_to_bimap(LABELS) + + @property + def num_spans(self): + return 2 + + def get_train_examples(self): + return self._create_examples(lines=read_json_lines(self.train_path), set_type="train") + + def get_val_examples(self): + return self._create_examples(lines=read_json_lines(self.val_path), set_type="val") + + def get_test_examples(self): + return self._create_examples(lines=read_json_lines(self.test_path), set_type="test") + + @classmethod + def _create_examples(cls, lines, set_type): + examples = [] + for line in lines: + examples.append( + Example( + # NOTE: WSCTask.super_glue_format_preds() is dependent on this guid format. + guid="%s-%s" % (set_type, line["idx"]), + text=line["text"], + span1_idx=line["span1_index"], + span2_idx=line["span2_index"], + span1_text=line["span1_text"], + span2_text=line["span2_text"], + label=line["label"] if set_type != "test" else cls.LABELS[-1], + ) + ) + return examples + + @classmethod + def super_glue_format_preds(cls, pred_dict): + """Reformat this task's raw predictions to have the structure expected by SuperGLUE.""" + lines = [] + for pred, guid in zip(list(pred_dict["preds"]), list(pred_dict["guids"])): + lines.append({"idx": int(guid.split("-")[1]), "label": str(cls.LABELS[pred])}) + return lines + + +def extract_char_span(full_text, span_text, space_index): + space_tokens = full_text.split() + extracted_span_text = space_tokens[space_index] + assert extracted_span_text.lower() in full_text.lower() + span_length = len(span_text) + if space_index == 0: + start = 0 + else: + start = len(" ".join(space_tokens[:space_index])) + 1 + # exclusive span + return ExclusiveSpan(start=start, end=start + span_length) diff --git a/jiant/tasks/lib/xnli.py b/jiant/tasks/lib/xnli.py new file mode 100644 index 000000000..ef3344e38 --- /dev/null +++ b/jiant/tasks/lib/xnli.py @@ -0,0 +1,113 @@ +import numpy as np +import torch +from dataclasses import dataclass +from typing import List + +from jiant.tasks.core import ( + BaseExample, + BaseTokenizedExample, + BaseDataRow, + BatchMixin, + Task, + TaskTypes, +) +from jiant.tasks.lib.templates.shared import double_sentence_featurize, labels_to_bimap +from jiant.utils.python.io import read_jsonl + + +@dataclass +class Example(BaseExample): + guid: str + input_premise: str + input_hypothesis: str + label: str + + def tokenize(self, tokenizer): + return TokenizedExample( + guid=self.guid, + input_premise=tokenizer.tokenize(self.input_premise), + input_hypothesis=tokenizer.tokenize(self.input_hypothesis), + label_id=XnliTask.LABEL_TO_ID[self.label], + ) + + +@dataclass +class TokenizedExample(BaseTokenizedExample): + guid: str + input_premise: List + input_hypothesis: List + label_id: int + + def featurize(self, tokenizer, feat_spec): + return double_sentence_featurize( + guid=self.guid, + input_tokens_a=self.input_premise, + input_tokens_b=self.input_hypothesis, + label_id=self.label_id, + tokenizer=tokenizer, + feat_spec=feat_spec, + data_row_class=DataRow, + ) + + +@dataclass +class DataRow(BaseDataRow): + guid: str + input_ids: np.ndarray + input_mask: np.ndarray + segment_ids: np.ndarray + label_id: int + tokens: list + + +@dataclass +class Batch(BatchMixin): + input_ids: torch.LongTensor + input_mask: torch.LongTensor + segment_ids: torch.LongTensor + label_id: torch.LongTensor + tokens: list + + +class XnliTask(Task): + Example = Example + TokenizedExample = Example + DataRow = DataRow + Batch = Batch + + TASK_TYPE = TaskTypes.CLASSIFICATION + LABELS = ["contradiction", "entailment", "neutral"] + LABEL_TO_ID, ID_TO_LABEL = labels_to_bimap(LABELS) + + def __init__(self, name, path_dict, language): + super().__init__(name=name, path_dict=path_dict) + self.language = language + + def get_train_examples(self): + raise NotImplementedError() + + def get_val_examples(self): + return self._create_examples( + lines=read_jsonl(self.val_path), set_type="val", language=self.language, + ) + + def get_test_examples(self): + return self._create_examples( + lines=read_jsonl(self.test_path), set_type="test", language=self.language, + ) + + @classmethod + def _create_examples(cls, lines, set_type, language): + examples = [] + for line in lines: + if line["language"] != language: + continue + examples.append( + Example( + guid="%s-%s" % (set_type, len(examples)), + input_premise=line["sentence1"], + input_hypothesis=line["sentence2"], + label=line["gold_label"] if set_type != "test" else cls.LABELS[-1], + ) + ) + return examples diff --git a/jiant/tasks/lib/xquad.py b/jiant/tasks/lib/xquad.py new file mode 100644 index 000000000..27dc45046 --- /dev/null +++ b/jiant/tasks/lib/xquad.py @@ -0,0 +1,54 @@ +from dataclasses import dataclass + +from jiant.tasks.lib.templates.squad_style import core as squad_style_template + + +@dataclass +class Example(squad_style_template.Example): + def tokenize(self, tokenizer): + raise NotImplementedError("SQuaD is weird") + + +@dataclass +class DataRow(squad_style_template.DataRow): + pass + + +@dataclass +class Batch(squad_style_template.Batch): + pass + + +class XquadTask(squad_style_template.BaseSquadStyleTask): + Example = Example + DataRow = DataRow + Batch = Batch + + def __init__( + self, + name, + path_dict, + language, + version_2_with_negative=False, + n_best_size=20, + max_answer_length=30, + null_score_diff_threshold=0.0, + ): + super().__init__( + name=name, + path_dict=path_dict, + version_2_with_negative=version_2_with_negative, + n_best_size=n_best_size, + max_answer_length=max_answer_length, + null_score_diff_threshold=null_score_diff_threshold, + ) + self.language = language + + def get_train_examples(self): + raise NotImplementedError("XQuAD does not have training examples") + + @classmethod + def read_squad_examples(cls, path, set_type): + return squad_style_template.generic_read_squad_examples( + path=path, set_type=set_type, example_class=cls.Example, + ) diff --git a/jiant/tasks/lm.py b/jiant/tasks/lm.py deleted file mode 100644 index 127244c43..000000000 --- a/jiant/tasks/lm.py +++ /dev/null @@ -1,383 +0,0 @@ -"""Task definitions for language modeling tasks.""" -import math -import os -import torch -from typing import Iterable, Sequence, Type -import random -import copy - -# Fields for instance processing -from allennlp.data import Instance -from allennlp.data.token_indexers import SingleIdTokenIndexer -from allennlp.training.metrics import Average -from allennlp.data.fields import SequenceLabelField, LabelField - -from jiant.utils.data_loaders import tokenize_and_truncate, get_tokenizer -from jiant.tasks.registry import register_task -from jiant.tasks.tasks import Task -from jiant.tasks.tasks import ( - UNK_TOK_ALLENNLP, - UNK_TOK_ATOMIC, - SequenceGenerationTask, - PairClassificationTask, - atomic_tokenize, - sentence_to_text_field, -) -from transformers import XLMRobertaTokenizer - - -class AutoregressiveLanguageModelingTask(SequenceGenerationTask): - """Generic language modeling task - See base class: SequenceGenerationTask - Attributes: - max_seq_len: (int) maximum sequence length - min_seq_len: (int) minimum sequence length - target_indexer: (Indexer Obejct) Indexer used for target - files_by_split: (dict) files for three data split (train, val, test) - """ - - def __init__(self, path, max_seq_len, name, **kw): - """Init class - Args: - path: (str) path that the data files are stored - max_seq_len: (int) maximum length of one sequence - name: (str) task name - """ - super().__init__(name, **kw) - self.scorer1 = Average() - self.scorer2 = None - self._label_namespace = self.name + "_labels" - self.val_metric = "%s_perplexity" % self.name - self.val_metric_decreases = True - self.max_seq_len = max_seq_len - self.min_seq_len = 0 - self.target_indexer = {"words": SingleIdTokenIndexer(namespace="tokens")} - self.files_by_split = { - "train": os.path.join(path, "train.txt"), - "val": os.path.join(path, "valid.txt"), - "test": os.path.join(path, "test.txt"), - } - - def count_examples(self): - """Computes number of samples - Assuming every line is one example. - """ - example_counts = {} - for split, split_path in self.files_by_split.items(): - example_counts[split] = sum(1 for _ in open(split_path)) - self.example_counts = example_counts - - def get_metrics(self, reset=False): - """Get metrics specific to the task - Args: - reset: (boolean) reset any accumulators or internal state - """ - nll = self.scorer1.get_metric(reset) - return {"perplexity": math.exp(nll)} - - def load_data(self): - # Data is exposed as iterable: no preloading - pass - - def get_data_iter(self, path): - """Loading data file and tokenizing the text - Args: - path: (str) data file path - """ - with open(path) as txt_fh: - for row in txt_fh: - toks = row.strip() - if not toks: - continue - yield tokenize_and_truncate(self._tokenizer_name, toks, self.max_seq_len) - - def process_split( - self, split, indexers, model_preprocessing_interface - ) -> Iterable[Type[Instance]]: - """Process a language modeling split by indexing and creating fields. - Args: - split: (list) a single list of sentences - indexers: (Indexer object) indexer to index input words - """ - - def _make_instance(sent_): - """ Forward targs adds as a target for input - and bwd targs adds as a target for input - to avoid issues with needing to strip extra tokens - in the input for each direction """ - sent_ = model_preprocessing_interface.boundary_token_fn(sent_) # Add and - d = { - "input": sentence_to_text_field(sent_, indexers), - "targs": sentence_to_text_field(sent_[1:] + [sent_[0]], self.target_indexer), - "targs_b": sentence_to_text_field([sent_[-1]] + sent_[:-1], self.target_indexer), - } - return Instance(d) - - for sent in split: - yield _make_instance(sent) - - def get_split_text(self, split: str): - """Get split text as iterable of records. - Args: - split: (str) should be one of 'train', 'val', or 'test'. - """ - return self.get_data_iter(self.files_by_split[split]) - - def get_sentences(self) -> Iterable[Sequence[str]]: - """Yield sentences, used to compute vocabulary. - """ - for split in self.files_by_split: - # Don't use test set for vocab building. - if split.startswith("test"): - continue - path = self.files_by_split[split] - for sent in self.get_data_iter(path): - yield sent - - -# TODO: restructure LM task hierarchy -@register_task("bwb", rel_path="BWB/") -class WikiTextLMTask(AutoregressiveLanguageModelingTask): - """ Language modeling on a Wikitext dataset - See base class: AutoregressiveLanguageModelingTask - """ - - def get_data_iter(self, path): - """ Rather than return a whole list of examples, stream them """ - nonatomics_toks = [UNK_TOK_ALLENNLP, ""] - with open(path) as txt_fh: - for row in txt_fh: - toks = row.strip() - if not toks: - continue - # WikiText103 preprocesses unknowns as '' - # which gets tokenized as '@', '@', 'UNKNOWN', ... - # We replace to avoid that - sent = atomic_tokenize( - toks, - UNK_TOK_ATOMIC, - nonatomics_toks, - self.max_seq_len, - tokenizer_name=self._tokenizer_name, - ) - # we also filtering out headers (artifact of the data) - # which are processed to have multiple = signs - if sent.count("=") >= 2 or len(toks) < self.min_seq_len + 2: - continue - yield sent - - -@register_task("wiki103", rel_path="WikiText103/") -class WikiText103LMTask(WikiTextLMTask): - """Language modeling task on Wikitext 103 - See base class: WikiTextLMTask - """ - - def __init__(self, path, *args, **kw): - super().__init__(path, *args, **kw) - self.files_by_split = { - "train": os.path.join(path, "train.sentences.txt"), - "val": os.path.join(path, "valid.sentences.txt"), - "test": os.path.join(path, "test.sentences.txt"), - } - - -@register_task("wikipedia_corpus_mlm", rel_path="wikipedia_corpus_small/") -class MaskedLanguageModelingTask(Task): - """ - Masked language modeling task on Wikipedia dataset - Attributes: - max_seq_len: (int) maximum sequence length - min_seq_len: (int) minimum sequence length - files_by_split: (dict) files for three data split (train, val, test) - We are currently using an unpreprocessed version of the Wikipedia corpus - that consists of 5% of the data. You can generate the data by following the - instructions from jiant/scripts/mlm. - """ - - def __init__(self, path, max_seq_len, name, **kw): - """Init class - Args: - path: (str) path that the data files are stored - max_seq_len: (int) maximum length of one sequence - name: (str) task name - """ - super().__init__(name, **kw) - self.scorer1 = Average() - self.scorer2 = None - self._label_namespace = "mlm" - self.val_metric = "%s_perplexity" % self.name - self.val_metric_decreases = True - self.max_seq_len = max_seq_len - self.min_seq_len = 0 - self.target_indexer = {"words": SingleIdTokenIndexer(namespace="tokens")} - self.files_by_split = { - "train": os.path.join(path, "train.txt"), - "val": os.path.join(path, "valid.txt"), - "test": os.path.join(path, "test.txt"), - } - - def load_data(self): - # Data is exposed as iterable: no preloading - pass - - def get_metrics(self, reset=False): - """Get metrics specific to the task - Args: - reset: (boolean) reset any accumulators or internal state - """ - nll = self.scorer1.get_metric(reset) - return {"perplexity": math.exp(nll)} - - def get_all_labels(self): - """ - For MLM, the label space is the vocabulary space of the input. - """ - labels = [] - tokenizer = get_tokenizer(self._tokenizer_name) - vocab_size = len(tokenizer) - ordered_vocab = tokenizer.convert_ids_to_tokens(range(vocab_size)) - for word in ordered_vocab: - labels.append(word) - return labels - - def update_metrics(self, out, batch=None): - self.scorer1(out["loss"].mean()) - return - - def get_data_iter(self, path): - """ - Loading data file and tokenizing the text. We treat the Wikipedia corpus as a - long sequence, and we take each slice of max_seq_len - 2 tokens as an example. The dataset - consists of a sentence per row in the file. This function concatenates all of the sentences, - before going through the sequence and yielding each chunk of max_seq_len - 2 tokens. - Args: - path: (str) data file path - """ - seq_len = self.max_seq_len - 2 - token_buffer = [] - tokenizer = get_tokenizer(self._tokenizer_name) - with open(path, "r", encoding="utf-8") as txt_fh: - for row in txt_fh: - toks = row.strip() - if not toks: - continue - toks = tokenizer.tokenize(toks) - token_buffer += toks - while len(token_buffer) > seq_len: - token_sequence = token_buffer[:seq_len] - token_buffer = token_buffer[seq_len:] - yield token_sequence - if token_buffer: - yield token_buffer - - def process_split( - self, split, indexers, model_preprocessing_interface - ) -> Iterable[Type[Instance]]: - """Process a language modeling split by indexing and creating fields. - Args: - split: (list) a single list of sentences - indexers: (Indexer object) indexer to index input words - """ - - def _make_instance(sent_): - sent_ = model_preprocessing_interface.boundary_token_fn(sent_) - input_sent = sentence_to_text_field(sent_, indexers) - d = { - "input": input_sent, - "targs": SequenceLabelField( - sent_, input_sent, label_namespace=self._label_namespace - ), - } - return Instance(d) - - for sent in split: - yield _make_instance(sent) - - def count_examples(self): - """Computes number of samples - Assuming every line is one example. - """ - example_counts = {} - for split, split_path in self.files_by_split.items(): - example_counts[split] = sum(1 for _ in self.get_data_iter(split_path)) - self.example_counts = example_counts - - def get_split_text(self, split: str): - """Get split text as iterable of records. - Args: - split: (str) should be one of 'train', 'val', or 'test'. - """ - return self.get_data_iter(self.files_by_split[split]) - - def get_sentences(self) -> Iterable[Sequence[str]]: - """Yield sentences, used to compute vocabulary. - """ - for split in self.files_by_split: - # Don't use test set for vocab building. - if split.startswith("test"): - continue - for sent in self.get_data_iter(self.files_by_split[split]): - yield sent - - def mlm_dynamic_masking(self, inputs, labels, mask_idx, tokenizer_name, sent_encoder): - """ - This function does dynamic masking as per the RoBERTa paper. Please refer to https://arxiv.org/abs/1907.11692 - for more details. - Parameters - ---------- - inputs: torch.Tensor(type=long), - labels torch.Tensor(type=long), - mask_idx: int - tokenizer_name: str, - sent_encoder: SentenceEncoder - - Returns - ------- - inputs: input after dynamic masking, - labels: labels after masking with -100, - indices_replaced: (testing purposes) indices that will be replaced by mask_idx, - indices_random: (testing purposes) indices that will be replaced by a random word, - masked_indices: (testing purposes) indices that the model will have to predict, - labels_after_shift: (testing purposes) labels after shifting but before masking - """ - mlm_probability = 0.15 - # We add 2 because we shift the inputs back by 2 in the forward function in sent encoder. - mask_idx += 2 - tokenizer = get_tokenizer(tokenizer_name) - # Masking code from https://github.com/huggingface/transformers/blob/master/examples/run_language_modeling.py - probability_matrix = torch.full(labels.shape, mlm_probability, device=inputs.device) - padding_mask = labels.eq(0) - probability_matrix.masked_fill_(padding_mask, value=0.0) - - masked_indices = torch.bernoulli(probability_matrix).to( - device=inputs.device, dtype=torch.uint8 - ) - tokenizer_name = sent_encoder._text_field_embedder.tokenizer_required - labels_after_shift, _ = sent_encoder._text_field_embedder.correct_sent_indexing( - {tokenizer_name: labels} - ) - # We only compute loss on masked tokens - # nn.CrossEntropy ignores the indices with value = -100 by default. - # Therefore, we replace non-masked indices with -100 so that they get ignored - # in loss computation. - labels = copy.deepcopy(labels_after_shift) - labels[~masked_indices] = -100 - - # 80% of the time, we replace masked input tokens with tokenizer.mask_token ([MASK]) - bernoulli_mask = torch.bernoulli(torch.full(labels.shape, 0.8)).to( - device=inputs.device, dtype=torch.uint8 - ) - indices_replaced = bernoulli_mask & masked_indices - inputs[indices_replaced] = mask_idx - - # 10% of the time, we replace masked input tokens with random word - bernoulli_mask = torch.bernoulli(torch.full(labels.shape, 0.5)).to( - device=inputs.device, dtype=torch.uint8 - ) - indices_random = bernoulli_mask & masked_indices & ~indices_replaced - random_words = torch.randint( - len(tokenizer), labels.shape, dtype=torch.long, device=inputs.device - ) - inputs[indices_random] = random_words[indices_random] - return inputs, labels, indices_replaced, indices_random, masked_indices, labels_after_shift diff --git a/jiant/tasks/lm_parsing.py b/jiant/tasks/lm_parsing.py deleted file mode 100644 index 105bde873..000000000 --- a/jiant/tasks/lm_parsing.py +++ /dev/null @@ -1,187 +0,0 @@ -""" -Task definitions for language modeling tasks set up to use for unsupervised parsing encoders. -Long term dependencies for language modeling: sentences concatenated together seperated by - token. -""" -import math -import os -from typing import Iterable, Type - -# Fields for instance processing -from allennlp.data import Instance -from allennlp.data.token_indexers import SingleIdTokenIndexer -from allennlp.training.metrics import Average - -from jiant.utils.data_loaders import load_tsv -from jiant.tasks.lm import AutoregressiveLanguageModelingTask -from jiant.tasks.registry import register_task -from jiant.tasks.tasks import sentence_to_text_field - - -class LanguageModelingParsingTask(AutoregressiveLanguageModelingTask): - def count_examples(self): - """Computes number of samples. - Every example is made up of sentences concatenated together, capped by max_seq_len. - """ - example_counts = {} - for split, split_path in self.files_by_split.items(): - arr = [line.strip().split() + [""] for line in open(split_path)] - allf = 0 - for x in arr: - allf += len(x) - example_counts[split] = int(math.ceil(allf / self.max_seq_len)) - self.example_counts = example_counts - - def process_split( - self, split, indexers, model_preprocessing_interface - ) -> Iterable[Type[Instance]]: - """Process a language modeling split by indexing and creating fields. - Args: - split: (list) a single list of sentences - indexers: (Indexer object) indexer to index input words - model_preprocessing_interface: ModelPreprocessingInterface object, in which - boundary_token_fn inserts start and end symbols for classification tasks. - Not used here. This may be a problem for GPT-2 or future LMs that use - non-standard boundary tokens. - """ - - def _make_instance(sent): - """ Forward targs adds as a target for input - and bwd targs adds as a target for input - to avoid issues with needing to strip extra tokens - in the input for each direction """ - d = {} - d["input"] = sentence_to_text_field(sent[:-1], indexers) - d["targs"] = sentence_to_text_field(sent[1:], self.target_indexer) - d["targs_b"] = sentence_to_text_field([sent[-1]] + sent[:-2], self.target_indexer) - return Instance(d) - - for sent in split: - yield _make_instance(sent) - - -@register_task("wsj", rel_path="WSJ/") -class WSJLanguageModelling(AutoregressiveLanguageModelingTask): - """ Language modeling on a PTB dataset - See base class: LanguageModelingTask - """ - - def get_data_iter(self, path): - """Load data file, tokenize text and concat sentences to create long term dependencies. - Args: - path: (str) data file path - """ - seq_len = self.max_seq_len - tokens = [] - with open(path) as txt_fh: - for row in txt_fh: - toks = row.strip() - if not toks: - continue - toks_v = toks.split() - toks = toks.split() + [""] - tokens += toks - for i in range(0, len(tokens), seq_len): - yield tokens[i : i + seq_len] - - -@register_task("toronto-lm", rel_path="toronto/") -class TorontoLanguageModelling(AutoregressiveLanguageModelingTask): - """ Language modeling on the Toronto Books dataset - See base class: LanguageModelingTask - """ - - def get_data_iter(self, path): - """Load data file, tokenize text and concat sentences to create long term dependencies. - Args: - path: (str) data file path - """ - seq_len = self.max_seq_len - tokens = [] - with open(path) as txt_fh: - for row in txt_fh: - toks = row.strip() - if not toks: - continue - toks_v = toks.split() - toks = toks.split() + [""] - tokens += toks - for i in range(0, len(tokens), seq_len): - yield tokens[i : i + seq_len] - - -@register_task("egw-lm", rel_path="egw_corpus/") -class EnglishgigawordLanguageModeling(AutoregressiveLanguageModelingTask): - """ Language modeling on the English Gigaword dataset - See base class: LanguageModelingTask - """ - - def get_data_iter(self, path): - """Load data file, tokenize text and concat sentences to create long term dependencies. - Args: - path: (str) data file path - """ - seq_len = self.max_seq_len - tokens = [] - with open(path) as txt_fh: - for row in txt_fh: - toks = row.strip() - if not toks: - continue - toks_v = toks.split() - toks = toks.split() + [""] - tokens += toks - for i in range(0, len(tokens), seq_len): - yield tokens[i : i + seq_len] - - -@register_task("mnli-lm", rel_path="MNLI/") -class MNLILanguageModeling(AutoregressiveLanguageModelingTask): - """ Language modeling on the MNLI dataset - See base class: LanguageModelingTask - """ - - def __init__(self, path, max_seq_len, name="mnli-lm", **kw): - """Init class - Args: - path: (str) path that the data files are stored - max_seq_len: (int) maximum length of one sequence - name: (str) task name - """ - super().__init__(path, max_seq_len, name, **kw) - self.scorer1 = Average() - self.scorer2 = None - self.val_metric = "%s_perplexity" % self.name - self.val_metric_decreases = True - self.max_seq_len = max_seq_len - self.min_seq_len = 0 - self.target_indexer = {"words": SingleIdTokenIndexer(namespace="tokens")} - self.files_by_split = { - "train": os.path.join(path, "train.tsv"), - "val": os.path.join(path, "dev_matched.tsv"), - "test": os.path.join(path, "test_matched.tsv"), - } - - def get_data_iter(self, path): - """ - Load data file (combine the entailment and contradiction sentence), tokenize text - and concat sentences to create long term dependencies. - Args: - path: (str) data file path - """ - seq_len = self.max_seq_len - targ_map = {"neutral": 0, "entailment": 1, "contradiction": 2} - data = load_tsv( - os.path.join(path), - 1000, - skip_rows=1, - s1_idx=8, - s2_idx=9, - targ_idx=11, - targ_map=targ_map, - ) - tokens = [] - for x, y in zip(data[0], data[1]): - tokens += x[1:-1] + [""] + y[1:-1] + [""] - for i in range(0, len(tokens), seq_len): - yield tokens[i : i + seq_len] diff --git a/jiant/tasks/nli_probing.py b/jiant/tasks/nli_probing.py deleted file mode 100644 index 5f2d21d0d..000000000 --- a/jiant/tasks/nli_probing.py +++ /dev/null @@ -1,201 +0,0 @@ -"""Task definitions for NLI probing tasks.""" -import logging as log -import os - -from jiant.utils.data_loaders import load_tsv -from jiant.tasks.registry import register_task -from jiant.tasks.tasks import PairClassificationTask - - -@register_task("nps", rel_path="nps/") -class NPSTask(PairClassificationTask): - def __init__(self, path, max_seq_len, name, **kw): - super(NPSTask, self).__init__(name, n_classes=3, **kw) - self.path = path - self.max_seq_len = max_seq_len - - self.train_data_text = None - self.val_data_text = None - self.test_data_text = None - - def load_data(self): - targ_map = {"neutral": 0, "entailment": 1, "contradiction": 2} - prob_data = load_tsv( - self._tokenizer_name, - os.path.join(self.path, "dev.tsv"), - max_seq_len=self.max_seq_len, - s1_idx=0, - s2_idx=1, - label_idx=2, - label_fn=targ_map.__getitem__, - skip_rows=0, - ) - self.train_data_text = self.val_data_text = self.test_data_text = prob_data - self.sentences = self.val_data_text[0] + self.val_data_text[1] - log.info("\tFinished loading NP/S data.") - - -@register_task("nli-prob", rel_path="NLI-Prob/") -class NLITypeProbingTask(PairClassificationTask): - """ Task class for Probing Task (NLI-type)""" - - def __init__(self, path, max_seq_len, name, probe_path="", **kw): - super(NLITypeProbingTask, self).__init__(name, n_classes=3, **kw) - self.path = path - self.max_seq_len = max_seq_len - self.probe_path = probe_path - - self.train_data_text = None - self.val_data_text = None - self.test_data_text = None - - def load_data(self): - targ_map = {"neutral": 0, "entailment": 1, "contradiction": 2} - prob_data = load_tsv( - data_file=os.path.join(self.path, self.probe_path), - max_seq_len=self.max_seq_len, - s1_idx=0, - s2_idx=1, - label_idx=2, - label_fn=targ_map.__getitem__, - skip_rows=0, - tokenizer_name=self._tokenizer_name, - ) - - self.train_data_text = self.val_data_text = self.test_data_text = prob_data - self.sentences = self.val_data_text[0] + self.val_data_text[1] - log.info("\tFinished loading NLI-type probing data.") - - -@register_task("nli-alt", rel_path="NLI-Prob/") -class NLITypeProbingAltTask(NLITypeProbingTask): - """ Task class for Alt Probing Task (NLI-type), NLITypeProbingTask with different indices""" - - def __init__(self, path, max_seq_len, name, probe_path="", **kw): - super(NLITypeProbingAltTask, self).__init__( - name=name, path=path, max_seq_len=max_seq_len, **kw - ) - self.path = path - self.max_seq_len = max_seq_len - self.probe_path = probe_path - - self.train_data_text = None - self.val_data_text = None - self.test_data_text = None - - def load_data(self): - targ_map = {"0": 0, "1": 1, "2": 2} - prob_data = load_tsv( - data_file=os.path.join(self.path, self.probe_path), - max_seq_len=self.max_seq_len, - s1_idx=9, - s2_idx=10, - label_idx=1, - label_fn=targ_map.__getitem__, - skip_rows=1, - return_indices=True, - tokenizer_name=self._tokenizer_name, - ) - - self.train_data_text = self.val_data_text = self.test_data_text = prob_data - self.sentences = self.val_data_text[0] + self.val_data_text[1] - log.info("\tFinished loading NLI-alt probing data.") - - -@register_task( - "nli-prob-prep", - rel_path="FunctionWordsProbing/nli-prep/", - s1_idx=8, - s2_idx=9, - label_idx=0, - skip_rows=1, -) -@register_task( - "nli-prob-negation", - rel_path="FunctionWordsProbing/nli-negation/", - s1_idx=8, - s2_idx=9, - label_idx=0, - skip_rows=1, -) -@register_task( - "nli-prob-spatial", - rel_path="FunctionWordsProbing/nli-spatial/", - idx_idx=0, - s1_idx=9, - s2_idx=10, - label_idx=0, - skip_rows=1, -) -@register_task( - "nli-prob-quant", - rel_path="FunctionWordsProbing/nli-quant/", - idx_idx=0, - s1_idx=9, - s2_idx=10, - label_idx=0, - skip_rows=1, -) -@register_task( - "nli-prob-comp", - rel_path="FunctionWordsProbing/nli-comp/", - idx_idx=0, - s1_idx=9, - s2_idx=10, - label_idx=0, - skip_rows=1, -) -class NLIProbingTask(PairClassificationTask): - """ Task class for NLI-type Probing Task - This probing task only have evaluation set, need to share classifier with NLI-type task. - At present, 5 tasks are registered under this class, - nli-prob-prep tests model's understanding of Prepositions - nli-prob-negation tests that of Negation - nli-prob-spatial tests that of Spatial Expressions - nli-prob-quant tests that of Quantification - nli-prob-comp tests that of Comparatives - """ - - def __init__( - self, - path, - max_seq_len, - name, - targ_map={"0": 0, "1": 1, "2": 2}, - idx_idx=None, - s1_idx=None, - s2_idx=None, - label_idx=None, - skip_rows=0, - **kw, - ): - super(NLIProbingTask, self).__init__(name, n_classes=3, **kw) - self.path = path - self.max_seq_len = max_seq_len - self.eval_only_task = True - - self.train_data_text = None - self.val_data_text = None - self.test_data_text = None - - self.targ_map = targ_map - self.s1_idx = s1_idx - self.s2_idx = s2_idx - self.label_idx = label_idx - self.skip_rows = skip_rows - - def load_data(self): - targ_map = self.targ_map - prob_data = load_tsv( - self._tokenizer_name, - os.path.join(self.path, "dev.tsv"), - max_seq_len=self.max_seq_len, - s1_idx=0, - s2_idx=1, - label_idx=2, - label_fn=targ_map.__getitem__, - skip_rows=0, - ) - self.train_data_text = self.val_data_text = self.test_data_text = prob_data - self.sentences = self.val_data_text[0] + self.val_data_text[1] - log.info("\tFinished loading NLI-type probing data on %s." % self.name) diff --git a/jiant/tasks/qa.py b/jiant/tasks/qa.py deleted file mode 100644 index f336e2f61..000000000 --- a/jiant/tasks/qa.py +++ /dev/null @@ -1,1007 +0,0 @@ -"""Task definitions for question answering tasks.""" -import os -import pandas as pd -import json -import collections -import gzip -import random -from typing import Iterable, Sequence, Type, Dict - -import torch -import logging as log -from allennlp.training.metrics import Average, F1Measure, CategoricalAccuracy -from allennlp.data.fields import LabelField, MetadataField -from allennlp.data import Instance -from jiant.allennlp_mods.numeric_field import NumericField -from jiant.metrics.span_metrics import ( - metric_max_over_ground_truths, - f1_score, - exact_match_score, - F1SpanMetric, - ExactMatchSpanMetric, -) - -from jiant.utils.data_loaders import tokenize_and_truncate -from jiant.utils.tokenizers import MosesTokenizer - -from jiant.tasks.tasks import Task, SpanPredictionTask, MultipleChoiceTask -from jiant.tasks.tasks import sentence_to_text_field -from jiant.tasks.registry import register_task -from ..utils.retokenize import space_tokenize_with_spans, find_space_token_span, get_aligner_fn - - -@register_task("multirc", rel_path="MultiRC/") -class MultiRCTask(Task): - """Multi-sentence Reading Comprehension task - See paper at https://cogcomp.org/multirc/ """ - - def __init__(self, path, max_seq_len, name, **kw): - super().__init__(name, **kw) - self.scorer1 = F1Measure(positive_label=1) - self.scorer2 = Average() # to delete - self.scorer3 = F1Measure(positive_label=1) - self._score_tracker = collections.defaultdict(list) - self.val_metric = "%s_avg" % self.name - self.val_metric_decreases = False - self.max_seq_len = max_seq_len - self.files_by_split = { - "train": os.path.join(path, "train.jsonl"), - "val": os.path.join(path, "val.jsonl"), - "test": os.path.join(path, "test.jsonl"), - } - - def load_data(self): - # Data is exposed as iterable: no preloading - pass - - def get_split_text(self, split: str): - """ Get split text as iterable of records. - - Split should be one of "train", "val", or "test". - """ - return self.load_data_for_path(self.files_by_split[split]) - - def load_data_for_path(self, path): - """ Load data """ - - with open(path, encoding="utf-8") as data_fh: - examples = [] - for example in data_fh: - ex = json.loads(example) - - assert ( - "version" in ex and ex["version"] == 1.1 - ), "MultiRC version is invalid! Example indices are likely incorrect. " - "Please re-download the data from super.gluebenchmark.com ." - - # each example has a passage field -> (text, questions) - # text is the passage, which requires some preprocessing - # questions is a list of questions, has fields (question, sentences_used, answers) - ex["passage"]["text"] = tokenize_and_truncate( - self.tokenizer_name, ex["passage"]["text"], self.max_seq_len - ) - for question in ex["passage"]["questions"]: - question["question"] = tokenize_and_truncate( - self.tokenizer_name, question["question"], self.max_seq_len - ) - for answer in question["answers"]: - answer["text"] = tokenize_and_truncate( - self.tokenizer_name, answer["text"], self.max_seq_len - ) - examples.append(ex) - return examples - - def get_sentences(self) -> Iterable[Sequence[str]]: - """ Yield sentences, used to compute vocabulary. """ - for split in self.files_by_split: - if split.startswith("test"): - continue - path = self.files_by_split[split] - for example in self.load_data_for_path(path): - yield example["passage"]["text"] - for question in example["passage"]["questions"]: - yield question["question"] - for answer in question["answers"]: - yield answer["text"] - - def process_split( - self, split, indexers, model_preprocessing_interface - ) -> Iterable[Type[Instance]]: - """ Process split text into a list of AllenNLP Instances. """ - - def _make_instance(passage, question, answer, label, par_idx, qst_idx, ans_idx): - """ pq_id: passage-question ID """ - d = {} - d["psg_str"] = MetadataField(" ".join(passage)) - d["qst_str"] = MetadataField(" ".join(question)) - d["ans_str"] = MetadataField(" ".join(answer)) - d["psg_idx"] = MetadataField(par_idx) - d["qst_idx"] = MetadataField(qst_idx) - d["ans_idx"] = MetadataField(ans_idx) - d["idx"] = MetadataField(ans_idx) # required by evaluate() - if model_preprocessing_interface.model_flags["uses_pair_embedding"]: - inp = model_preprocessing_interface.boundary_token_fn(para, question + answer) - d["psg_qst_ans"] = sentence_to_text_field(inp, indexers) - else: - d["psg"] = sentence_to_text_field( - model_preprocessing_interface.boundary_token_fn(passage), indexers - ) - d["qst"] = sentence_to_text_field( - model_preprocessing_interface.boundary_token_fn(question), indexers - ) - d["ans"] = sentence_to_text_field( - model_preprocessing_interface.boundary_token_fn(answer), indexers - ) - d["label"] = LabelField(label, label_namespace="labels", skip_indexing=True) - - return Instance(d) - - for example in split: - par_idx = example["idx"] - para = example["passage"]["text"] - for ex in example["passage"]["questions"]: - qst_idx = ex["idx"] - question = ex["question"] - for answer in ex["answers"]: - ans_idx = answer["idx"] - ans = answer["text"] - label = int(answer["label"]) if "label" in answer else 0 - yield _make_instance(para, question, ans, label, par_idx, qst_idx, ans_idx) - - def count_examples(self): - """ Compute here b/c we"re streaming the sentences. """ - example_counts = {} - for split, split_path in self.files_by_split.items(): - example_counts[split] = sum( - len(q["answers"]) - for r in open(split_path, "r", encoding="utf-8") - for q in json.loads(r)["passage"]["questions"] - ) - - self.example_counts = example_counts - - def update_metrics(self, out, batch): - logits, labels = out["logits"], batch["label"] - idxs = [(p, q) for p, q in zip(batch["psg_idx"], batch["qst_idx"])] - """ A batch of logits, labels, and the passage+questions they go with """ - self.scorer1(logits, labels) - logits, labels = logits.detach().cpu(), labels.detach().cpu() - # track progress on each question - for ex, logit, label in zip(idxs, logits, labels): - self._score_tracker[ex].append((logit, label)) - - def get_metrics(self, reset=False): - """Get metrics specific to the task""" - _, _, ans_f1 = self.scorer1.get_metric(reset) - - ems, f1s = [], [] - for logits_and_labels in self._score_tracker.values(): - logits, labels = list(zip(*logits_and_labels)) - logits = torch.stack(logits) - labels = torch.stack(labels) - - # question F1 - self.scorer3(logits, labels) - __, _, ex_f1 = self.scorer3.get_metric(reset=True) - f1s.append(ex_f1) - - # EM - preds = logits.argmax(dim=-1) - ex_em = (torch.eq(preds, labels).sum() == preds.nelement()).item() - ems.append(ex_em) - em = sum(ems) / len(ems) - qst_f1 = sum(f1s) / len(f1s) - - if reset: - self._score_tracker = collections.defaultdict(list) - - return {"ans_f1": ans_f1, "qst_f1": qst_f1, "em": em, "avg": (ans_f1 + em) / 2} - - -@register_task("record", rel_path="ReCoRD/") -class ReCoRDTask(Task): - """Reading Comprehension with commonsense Reasoning Dataset - See paper at https://sheng-z.github.io/ReCoRD-explorer """ - - def __init__(self, path, max_seq_len, name, **kw): - super().__init__(name, **kw) - self.val_metric = "%s_avg" % self.name - self.val_metric_decreases = False - self._score_tracker = collections.defaultdict(list) - self._answers = None - self.max_seq_len = max_seq_len - self.files_by_split = { - "train": os.path.join(path, "train.jsonl"), - "val": os.path.join(path, "val.jsonl"), - "test": os.path.join(path, "test.jsonl"), - } - - def load_data(self): - # Data is exposed as iterable: no preloading - pass - - def get_split_text(self, split: str): - """ Get split text as iterable of records. - - Split should be one of "train", "val", or "test". - """ - return self.load_data_for_path(self.files_by_split[split], split) - - def load_data_for_path(self, path, split): - """ Load data """ - - examples = [] - data = [json.loads(d) for d in open(path, encoding="utf-8")] - for item in data: - psg_id = item["idx"] - psg = tokenize_and_truncate( - self.tokenizer_name, item["passage"]["text"], self.max_seq_len - ) - ent_idxs = item["passage"]["entities"] - ents = [item["passage"]["text"][idx["start"] : idx["end"] + 1] for idx in ent_idxs] - qas = item["qas"] - for qa in qas: - qst = qa["query"] - qst_id = qa["idx"] - if "answers" in qa: - anss = [a["text"] for a in qa["answers"]] - else: - anss = [] - ex = { - "passage": psg, - "ents": ents, - "query": qst, - "answers": anss, - "psg_id": f"{split}-{psg_id}", - "qst_id": qst_id, - } - examples.append(ex) - - return examples - - def _load_answers(self) -> None: - answers = {} - for split, split_path in self.files_by_split.items(): - data = [json.loads(d) for d in open(split_path, encoding="utf-8")] - for item in data: - psg_id = f"{split}-{item['idx']}" - for qa in item["qas"]: - qst_id = qa["idx"] - if "answers" in qa: - answers[(psg_id, qst_id)] = [a["text"] for a in qa["answers"]] - else: - answers[(psg_id, qst_id)] = ["No answer"] - self._answers = answers - - def get_sentences(self) -> Iterable[Sequence[str]]: - """ Yield sentences, used to compute vocabulary. """ - for split in self.files_by_split: - if split.startswith("test"): - continue - path = self.files_by_split[split] - for example in self.load_data_for_path(path, split): - yield example["passage"] - yield example["query"] - - def process_split( - self, split, indexers, model_preprocessing_interface - ) -> Iterable[Type[Instance]]: - """ Process split text into a list of AllenNLP Instances. """ - - def is_answer(x, ys): - """ Given a list of answers, determine if x is an answer """ - return x in ys - - def insert_ent(ent, template): - """ Replace ent into template (query with @placeholder) """ - len(template.split("@placeholder")) == 2, "No placeholder detected!" - return template.replace("@placeholder", ent) - - def _make_instance(psg, qst, ans_str, label, psg_idx, qst_idx, ans_idx): - """ pq_id: passage-question ID """ - d = {} - d["psg_str"] = MetadataField(" ".join(psg)) - d["qst_str"] = MetadataField(" ".join(qst)) - d["ans_str"] = MetadataField(ans_str) - d["psg_idx"] = MetadataField(par_idx) - d["qst_idx"] = MetadataField(qst_idx) - d["ans_idx"] = MetadataField(ans_idx) - d["idx"] = MetadataField(ans_idx) # required by evaluate() - if model_preprocessing_interface.model_flags["uses_pair_embedding"]: - inp = model_preprocessing_interface.boundary_token_fn(psg, qst) - d["psg_qst_ans"] = sentence_to_text_field(inp, indexers) - else: - d["psg"] = sentence_to_text_field( - model_preprocessing_interface.boundary_token_fn(psg), indexers - ) - d["qst"] = sentence_to_text_field( - model_preprocessing_interface.boundary_token_fn(qst), indexers - ) - d["label"] = LabelField(label, label_namespace="labels", skip_indexing=True) - - return Instance(d) - - for example in split: - psg = example["passage"] - qst_template = example["query"] - - ents = example["ents"] - - anss = example["answers"] - par_idx = example["psg_id"] - qst_idx = example["qst_id"] - for ent_idx, ent in enumerate(ents): - label = is_answer(ent, anss) - qst = tokenize_and_truncate( - self.tokenizer_name, insert_ent(ent, qst_template), self.max_seq_len - ) - yield _make_instance(psg, qst, ent, label, par_idx, qst_idx, ent_idx) - - def count_examples(self): - """ Compute here b/c we're streaming the sentences. """ - example_counts = {} - for split, split_path in self.files_by_split.items(): - data = [json.loads(d) for d in open(split_path, encoding="utf-8")] - example_counts[split] = sum([len(d["passage"]["entities"]) for d in data]) - self.example_counts = example_counts - - def update_metrics(self, out, batch): - """ A batch of logits+answer strings and the questions they go with """ - logits = out["logits"] - anss = batch["ans_str"] - idxs = [(p, q) for p, q in zip(batch["psg_idx"], batch["qst_idx"])] - logits = logits.detach().cpu() - for idx, logit, ans in zip(idxs, logits, anss): - self._score_tracker[idx].append((logit, ans)) - - def get_metrics(self, reset=False): - """Get metrics specific to the task""" - - # Load answers, used for computing metrics - if self._answers is None: - self._load_answers() - - ems, f1s = [], [] - for idx, logits_and_anss in self._score_tracker.items(): - golds = self._answers[idx] - logits_and_anss.sort(key=lambda x: x[1]) - logits, anss = list(zip(*logits_and_anss)) - logits = torch.stack(logits) - - # take the most probable choice as the model prediction - pred_idx = torch.softmax(logits, dim=-1)[:, -1].argmax().item() - pred = anss[pred_idx] - - # F1 - f1 = metric_max_over_ground_truths(f1_score, pred, golds) - f1s.append(f1) - - # EM - em = metric_max_over_ground_truths(exact_match_score, pred, golds) - ems.append(em) - - em = sum(ems) / len(ems) - f1 = sum(f1s) / len(f1s) - - if reset: - self._score_tracker = collections.defaultdict(list) - - return {"f1": f1, "em": em, "avg": (f1 + em) / 2} - - -@register_task("qasrl", rel_path="QASRL/") -class QASRLTask(SpanPredictionTask): - def __init__(self, path, max_seq_len, name, **kw): - """QA-SRL (Question-Answer Driven Semantic Role Labeling) - See http://qasrl.org/ - Download, unzip, and rename the "qasrl-v2" folder to "QASRL" - """ - super(QASRLTask, self).__init__(name, **kw) - self.path = path - self.max_seq_len = max_seq_len - - self.train_data_text = None - self.val_data_text = None - self.test_data_text = None - - self.f1_metric = F1SpanMetric() - self.em_metric = ExactMatchSpanMetric() - - self.val_metric = "%s_avg" % self.name - self.val_metric_decreases = False - - def count_examples(self, splits=["train", "val", "test"]): - """ Count examples in the dataset. """ - pass - - def get_metrics(self, reset: bool = False) -> Dict: - f1 = self.f1_metric.get_metric(reset) - em = self.em_metric.get_metric(reset) - collected_metrics = {"f1": f1, "em": em, "avg": (f1 + em) / 2} - return collected_metrics - - def load_data(self): - self.train_data_text = self._load_file(os.path.join(self.path, "orig", "train.jsonl.gz")) - - # Shuffle val_data to ensure diversity in periodic validation with val_data_limit - self.val_data_text = self._load_file( - os.path.join(self.path, "orig", "dev.jsonl.gz"), shuffle=True - ) - - self.test_data_text = self._load_file(os.path.join(self.path, "orig", "test.jsonl.gz")) - - self.sentences = ( - [example["passage"] for example in self.train_data_text] - + [example["question"] for example in self.train_data_text] - + [example["passage"] for example in self.val_data_text] - + [example["question"] for example in self.val_data_text] - ) - self.example_counts = { - "train": len(self.train_data_text), - "val": len(self.val_data_text), - "test": len(self.test_data_text), - } - - def get_sentences(self) -> Iterable[Sequence[str]]: - """ Yield sentences, used to compute vocabulary. """ - yield from self.sentences - - def process_split( - self, split, indexers, model_preprocessing_interface - ) -> Iterable[Type[Instance]]: - def _make_instance(example): - d = dict() - - # For human-readability - d["raw_passage"] = MetadataField(" ".join(example["passage"])) - d["raw_question"] = MetadataField(" ".join(example["question"])) - - if model_preprocessing_interface.model_flags["uses_pair_embedding"]: - inp, start_offset, _ = model_preprocessing_interface.boundary_token_fn( - example["passage"], example["question"], get_offset=True - ) - d["inputs"] = sentence_to_text_field(inp, indexers) - else: - d["passage"] = sentence_to_text_field( - model_preprocessing_interface.boundary_token_fn(example["passage"]), indexers - ) - d["question"] = sentence_to_text_field( - model_preprocessing_interface.boundary_token_fn(example["question"]), indexers - ) - start_offset = 0 - d["span_start"] = NumericField( - example["answer_span"][0] + start_offset, label_namespace="span_start_labels" - ) - d["span_end"] = NumericField( - example["answer_span"][1] + start_offset, label_namespace="span_end_labels" - ) - d["start_offset"] = MetadataField(start_offset) - d["passage_str"] = MetadataField(example["passage_str"]) - d["answer_str"] = MetadataField(example["answer_str"]) - d["space_processed_token_map"] = MetadataField(example["space_processed_token_map"]) - return Instance(d) - - instances = map(_make_instance, split) - return instances - - def _load_file(self, path, shuffle=False): - example_list = [] - moses = MosesTokenizer() - failed = 0 - with gzip.open(path) as f: - lines = f.read().splitlines() - - for line in lines: - datum = self.preprocess_qasrl_datum(json.loads(line)) - for entry in datum["entries"]: - for question, answer_list in entry["questions"].items(): - for answer in answer_list: - for answer_span in answer: - answer_tok_span = ( - answer_span["span"][0], - answer_span["span"][1] + 1, # exclusive - ) - try: - remapped_result = remap_ptb_passage_and_answer_spans( - ptb_tokens=datum["sentence_tokens"], - answer_span=answer_tok_span, - moses=moses, - # We can move the aligned outside the loop, actually - tokenizer_name=self.tokenizer_name, - ) - except ValueError: - failed += 1 - continue - example_list.append( - { - "passage": self._process_sentence( - remapped_result["detok_sent"] - ), - "question": self._process_sentence(question), - "answer_span": remapped_result["answer_token_span"], - "passage_str": remapped_result["detok_sent"], - "answer_str": remapped_result["answer_str"], - "space_processed_token_map": remapped_result[ - "space_processed_token_map" - ], - } - ) - - if failed: - log.info("FAILED ({}): {}".format(failed, path)) - - if shuffle: - random.Random(1234).shuffle(example_list) - return example_list - - def _process_sentence(self, sent): - return tokenize_and_truncate( - tokenizer_name=self.tokenizer_name, sent=sent, max_seq_len=self.max_seq_len - ) - - def get_split_text(self, split: str): - return getattr(self, "%s_data_text" % split) - - @classmethod - def preprocess_qasrl_datum(cls, datum): - """ Extract relevant fields """ - return { - "sentence_tokens": datum["sentenceTokens"], - "entries": [ - { - "verb": verb_entry["verbInflectedForms"]["stem"], - "verb_idx": verb_idx, - "questions": { - question: [ - [ - { - "tokens": datum["sentenceTokens"][span[0] : span[1] + 1], - "span": span, - } - for span in answer_judgment["spans"] - ] - for answer_judgment in q_data["answerJudgments"] - if answer_judgment["isValid"] - ] - for question, q_data in verb_entry["questionLabels"].items() - }, - } - for verb_idx, verb_entry in datum["verbEntries"].items() - ], - } - - -@register_task("qamr", rel_path="QAMR/") -class QAMRTask(SpanPredictionTask): - """ Question-Answer Meaning Representation (QAMR) - https://github.com/uwnlp/qamr - """ - - def __init__(self, path, max_seq_len, name="qamr", **kw): - self.path = path - super(QAMRTask, self).__init__(name, **kw) - self.max_seq_len = max_seq_len - - self.train_data_text = None - self.val_data_text = None - self.test_data_text = None - - self.f1_metric = F1SpanMetric() - self.em_metric = ExactMatchSpanMetric() - - self.val_metric = "%s_avg" % self.name - self.val_metric_decreases = False - - def get_metrics(self, reset: bool = False) -> Dict: - f1 = self.f1_metric.get_metric(reset) - em = self.em_metric.get_metric(reset) - collected_metrics = {"f1": f1, "em": em, "avg": (f1 + em) / 2} - return collected_metrics - - def get_sentences(self) -> Iterable[Sequence[str]]: - """ Yield sentences, used to compute vocabulary. """ - yield from self.sentences - - def process_split( - self, split, indexers, model_preprocessing_interface - ) -> Iterable[Type[Instance]]: - def _make_instance(example): - d = dict() - - # For human-readability - d["raw_passage"] = MetadataField(" ".join(example["passage"])) - d["raw_question"] = MetadataField(" ".join(example["question"])) - - if model_preprocessing_interface.model_flags["uses_pair_embedding"]: - inp, start_offset, _ = model_preprocessing_interface.boundary_token_fn( - example["passage"], example["question"], get_offset=True - ) - d["inputs"] = sentence_to_text_field(inp, indexers) - else: - d["passage"] = sentence_to_text_field( - model_preprocessing_interface.boundary_token_fn(example["passage"]), indexers - ) - d["question"] = sentence_to_text_field( - model_preprocessing_interface.boundary_token_fn(example["question"]), indexers - ) - start_offset = 0 - d["span_start"] = NumericField( - example["answer_span"][0] + start_offset, label_namespace="span_start_labels" - ) - d["span_end"] = NumericField( - example["answer_span"][1] + start_offset, label_namespace="span_end_labels" - ) - d["start_offset"] = MetadataField(start_offset) - d["passage_str"] = MetadataField(example["passage_str"]) - d["answer_str"] = MetadataField(example["answer_str"]) - d["space_processed_token_map"] = MetadataField(example["space_processed_token_map"]) - return Instance(d) - - instances = map(_make_instance, split) - return instances - - def get_split_text(self, split: str): - return getattr(self, "%s_data_text" % split) - - @classmethod - def load_tsv_dataset(cls, path, wiki_dict): - df = pd.read_csv( - path, - sep="\t", - header=None, - names=[ - "sent_id", - "target_ids", - "worker_id", - "qa_index", - "qa_word", - "question", - "answer", - "response1", - "response2", - ], - ) - df["sent"] = df["sent_id"].apply(wiki_dict.get) - return df - - def process_dataset(self, data_df, shuffle=False): - example_list = [] - moses = MosesTokenizer() - for i, row in data_df.iterrows(): - # Answer indices are a space-limited list of numbers. - # We simply take the min/max of the indices - answer_idxs = list(map(int, row["answer"].split())) - ans_tok_start, ans_tok_end = min(answer_idxs), max(answer_idxs) + 1 # Exclusive - - remapped_result = remap_ptb_passage_and_answer_spans( - ptb_tokens=row["sent"].split(), - answer_span=(ans_tok_start, ans_tok_end), - moses=moses, - tokenizer_name=self.tokenizer_name, - ) - example_list.append( - { - "passage": self._process_sentence(remapped_result["detok_sent"]), - "question": self._process_sentence(row["question"]), - "answer_span": remapped_result["answer_token_span"], - "passage_str": remapped_result["detok_sent"], - "answer_str": remapped_result["answer_str"], - "space_processed_token_map": remapped_result["space_processed_token_map"], - } - ) - - if shuffle: - random.Random(12345).shuffle(example_list) - - return example_list - - def _process_sentence(self, sent): - return tokenize_and_truncate( - tokenizer_name=self.tokenizer_name, sent=sent, max_seq_len=self.max_seq_len - ) - - @classmethod - def load_wiki_dict(cls, path): - wiki_df = pd.read_csv(path, sep="\t", names=["sent_id", "text"]) - wiki_dict = {row["sent_id"]: row["text"] for _, row in wiki_df.iterrows()} - return wiki_dict - - def load_data(self): - wiki_dict = self.load_wiki_dict(os.path.join(self.path, "qamr/data/wiki-sentences.tsv")) - self.train_data_text = self.process_dataset( - self.load_tsv_dataset( - path=os.path.join(self.path, "qamr/data/filtered/train.tsv"), wiki_dict=wiki_dict - ) - ) - self.val_data_text = self.process_dataset( - self.load_tsv_dataset( - path=os.path.join(self.path, "qamr/data/filtered/dev.tsv"), wiki_dict=wiki_dict - ), - shuffle=True, - ) - self.test_data_text = self.process_dataset( - self.load_tsv_dataset( - path=os.path.join(self.path, "qamr/data/filtered/test.tsv"), wiki_dict=wiki_dict - ) - ) - - self.sentences = ( - [example["passage"] for example in self.train_data_text] - + [example["question"] for example in self.train_data_text] - + [example["passage"] for example in self.val_data_text] - + [example["question"] for example in self.val_data_text] - ) - self.example_counts = { - "train": len(self.train_data_text), - "val": len(self.val_data_text), - "test": len(self.test_data_text), - } - - @staticmethod - def collapse_contiguous_indices(ls): - """ - [2, 3, 4, 5, 6, 7, 8] -> [(2, 9)] - [1, 2, 4, 5] -> [(1, 3), (4, 6)] - """ - if not ls: - return [] - output = [] - start = None - prev = None - for n in ls: - if start is None: - start = n - prev = n - elif n == prev + 1: - prev += 1 - continue - else: - output.append((start, prev + 1)) # exclusive - start = n - prev = n - output.append((start, prev + 1)) # exclusive - return output - - -def remap_ptb_passage_and_answer_spans(ptb_tokens, answer_span, moses, tokenizer_name): - # Start with PTB tokenized tokens - # The answer_span is also in ptb_token space. We first want to detokenize, and convert - # everything to space-tokenization space. - - # Detokenize the passage. Everything we do will be based on the detokenized input, - # INCLUDING evaluation. - detok_sent = moses.detokenize_ptb(ptb_tokens) - - # Answer indices are a space-limited list of numbers. - # We simply take the min/max of the indices - ans_tok_start, ans_tok_end = answer_span[0], answer_span[1] # Exclusive - # We convert the PTB-tokenized answer to char-indices. - ans_char_start = len(moses.detokenize_ptb(ptb_tokens[:ans_tok_start])) - while detok_sent[ans_char_start] == " ": - ans_char_start += 1 - ans_char_end = len(moses.detokenize_ptb(ptb_tokens[:ans_tok_end])) - answer_str = detok_sent[ans_char_start:ans_char_end].strip() - - # We space-tokenize, with the accompanying char-indices. - # We use the char-indices to map the answers to space-tokens. - space_tokens_with_spans = space_tokenize_with_spans(detok_sent) - ans_space_token_span = find_space_token_span( - space_tokens_with_spans=space_tokens_with_spans, - char_start=ans_char_start, - char_end=ans_char_end, - ) - # We project the space-tokenized answer to processed-tokens (e.g. BERT). - # The latter is used for training/predicting. - aligner_fn = get_aligner_fn(tokenizer_name) - token_aligner, actual_tokens = aligner_fn(detok_sent) - - # space_processed_token_map is a list of tuples - # (space_token, processed_token (e.g. BERT), space_token_index) - # We will need this to map from token predictions to str spans - space_processed_token_map = [ - (actual_tokens[actual_idx], space_token, space_idx) - for space_idx, (space_token, _, _) in enumerate(space_tokens_with_spans) - for actual_idx in token_aligner.project_tokens(space_idx) - ] - ans_actual_token_span = token_aligner.project_span(*ans_space_token_span) - - return { - "detok_sent": detok_sent, - "answer_token_span": ans_actual_token_span, - "answer_str": answer_str, - "space_processed_token_map": space_processed_token_map, - } - - -@register_task("commonsenseqa", rel_path="CommonsenseQA/") -@register_task("commonsenseqa-easy", rel_path="CommonsenseQA/", easy=True) -class CommonsenseQATask(MultipleChoiceTask): - """ Task class for CommonsenseQA Task. """ - - def __init__(self, path, max_seq_len, name, easy=False, **kw): - super().__init__(name, **kw) - self.path = path - self.max_seq_len = max_seq_len - - self.easy = easy - self.train_data_text = None - self.val_data_text = None - self.test_data_text = None - - self.scorer1 = CategoricalAccuracy() - self.scorers = [self.scorer1] - self.val_metric = "%s_accuracy" % name - self.val_metric_decreases = False - self.n_choices = 5 - self.label2choice_idx = {"A": 0, "B": 1, "C": 2, "D": 3, "E": 4} - self.choice_idx2label = ["A", "B", "C", "D", "E"] - - def load_data(self): - """ Process the dataset located at path. """ - - def _load_split(data_file): - questions, choices, targs, id_str = [], [], [], [] - data = [json.loads(l) for l in open(data_file, encoding="utf-8")] - for example in data: - question = tokenize_and_truncate( - self._tokenizer_name, "Q:" + example["question"]["stem"], self.max_seq_len - ) - choices_dict = { - a_choice["label"]: tokenize_and_truncate( - self._tokenizer_name, "A:" + a_choice["text"], self.max_seq_len - ) - for a_choice in example["question"]["choices"] - } - multiple_choices = [choices_dict[label] for label in self.choice_idx2label] - targ = self.label2choice_idx[example["answerKey"]] if "answerKey" in example else 0 - example_id = example["id"] - questions.append(question) - choices.append(multiple_choices) - targs.append(targ) - id_str.append(example_id) - return [questions, choices, targs, id_str] - - train_file = "train_rand_split_EASY.jsonl" if self.easy else "train_rand_split.jsonl" - val_file = "dev_rand_split_EASY.jsonl" if self.easy else "dev_rand_split.jsonl" - test_file = "test_rand_split_no_answers.jsonl" - self.train_data_text = _load_split(os.path.join(self.path, train_file)) - self.val_data_text = _load_split(os.path.join(self.path, val_file)) - self.test_data_text = _load_split(os.path.join(self.path, test_file)) - self.sentences = ( - self.train_data_text[0] - + self.val_data_text[0] - + [choice for choices in self.train_data_text[1] for choice in choices] - + [choice for choices in self.val_data_text[1] for choice in choices] - ) - log.info("\tFinished loading CommonsenseQA data.") - - def process_split( - self, split, indexers, model_preprocessing_interface - ) -> Iterable[Type[Instance]]: - """ Process split text into a list of AllenNLP Instances. """ - - def _make_instance(question, choices, label, id_str): - d = {} - d["question_str"] = MetadataField(" ".join(question)) - if not model_preprocessing_interface.model_flags["uses_pair_embedding"]: - d["question"] = sentence_to_text_field( - model_preprocessing_interface.boundary_token_fn(question), indexers - ) - for choice_idx, choice in enumerate(choices): - inp = ( - model_preprocessing_interface.boundary_token_fn(question, choice) - if model_preprocessing_interface.model_flags["uses_pair_embedding"] - else model_preprocessing_interface.boundary_token_fn(choice) - ) - d["choice%d" % choice_idx] = sentence_to_text_field(inp, indexers) - d["choice%d_str" % choice_idx] = MetadataField(" ".join(choice)) - d["label"] = LabelField(label, label_namespace="labels", skip_indexing=True) - d["id_str"] = MetadataField(id_str) - return Instance(d) - - split = list(split) - instances = map(_make_instance, *split) - return instances - - def get_metrics(self, reset=False): - """Get metrics specific to the task""" - acc = self.scorer1.get_metric(reset) - return {"accuracy": acc} - - -@register_task("cosmosqa", rel_path="cosmosqa/") -class CosmosQATask(MultipleChoiceTask): - """ Task class for CosmosQA Task. - adaptation of preprocessing from - https://github.com/wilburOne/cosmosqa """ - - def __init__(self, path, max_seq_len, name, **kw): - super().__init__(name, **kw) - self.path = path - self.max_seq_len = max_seq_len - - self.train_data_text = None - self.val_data_text = None - self.test_data_text = None - - self.scorer1 = CategoricalAccuracy() - self.scorers = [self.scorer1] - self.val_metric = "%s_accuracy" % name - self.val_metric_decreases = False - self.n_choices = 4 - - def load_data(self): - """ Process the dataset located at path. """ - self.train_data_text = self._load_csv(os.path.join(self.path, "train.csv")) - self.val_data_text = self._load_csv(os.path.join(self.path, "valid.csv")) - self.test_data_text = self._load_csv(os.path.join(self.path, "test_no_label.csv")) - self.sentences = ( - self.train_data_text[0] - + self.val_data_text[0] - + [choice for choices in self.train_data_text[1] for choice in choices] - + [choice for choices in self.val_data_text[1] for choice in choices] - ) - log.info("\tFinished loading CosmosQA data.") - - def _load_csv(self, input_file): - import csv - - with open(input_file, "r") as csv_file: - reader = csv.DictReader(csv_file) - records = [record for record in reader] - - contexts, choices, targs, id_str = [], [], [], [] - for record in records: - question = record["question"] - - ans_choices = [record["answer" + str(i)] for i in range(self.n_choices)] - qa_tok_choices = [ - tokenize_and_truncate( - self._tokenizer_name, question + " " + ans_choices[i], self.max_seq_len - ) - for i in range(len(ans_choices)) - ] - max_ans_len = max([len(tok) for tok in qa_tok_choices]) - context = tokenize_and_truncate( - self._tokenizer_name, record["context"], self.max_seq_len - max_ans_len - ) - targ = int(record["label"]) if "label" in record else 0 - idx = record["id"] - contexts.append(context) - choices.append(qa_tok_choices) - targs.append(targ) - id_str.append(idx) - return [contexts, choices, targs, id_str] - - def process_split( - self, split, indexers, model_preprocessing_interface - ) -> Iterable[Type[Instance]]: - """ Process split text into a list of AllenNLP Instances. """ - - def _make_instance(context, choices, label, id_str): - d = {} - d["context_str"] = MetadataField(" ".join(context)) - if not model_preprocessing_interface.model_flags["uses_pair_embedding"]: - d["context"] = sentence_to_text_field( - model_preprocessing_interface.boundary_token_fn(context), indexers - ) - for choice_idx, choice in enumerate(choices): - inp = ( - model_preprocessing_interface.boundary_token_fn(context, choice) - if model_preprocessing_interface.model_flags["uses_pair_embedding"] - else model_preprocessing_interface.boundary_token_fn(choice) - ) - d["choice%d" % choice_idx] = sentence_to_text_field(inp, indexers) - d["choice%d_str" % choice_idx] = MetadataField(" ".join(choice)) - d["label"] = LabelField(label, label_namespace="labels", skip_indexing=True) - d["id_str"] = MetadataField(id_str) - return Instance(d) - - split = list(split) - instances = map(_make_instance, *split) - return instances - - def get_metrics(self, reset=False): - """Get metrics specific to the task""" - acc = self.scorer1.get_metric(reset) - return {"accuracy": acc} diff --git a/jiant/tasks/registry.py b/jiant/tasks/registry.py deleted file mode 100644 index 04ec6ec2e..000000000 --- a/jiant/tasks/registry.py +++ /dev/null @@ -1,29 +0,0 @@ -"""Global task registry. - -Import this to use @register_task when defining new tasks, -then access the registry as registry.REGISTRY. -""" - -# Entries have form name -> (cls, rel_path, kw) -REGISTRY = {} # Do not edit manually! - - -def register_task(name, rel_path, **kw): - """Decorator to register a task. - - Use this instead of adding to NAME2INFO in preprocess.py - - If kw is not empty, this will be passed as additional args when the Task is - constructed in preprocess.py. - - Usage: - @register_task('mytask', 'my-task/data', **extra_kw) - class MyTask(SingleClassificationTask): - ... - """ - - def _wrap(cls): - REGISTRY[name] = (cls, rel_path, kw) - return cls - - return _wrap diff --git a/jiant/tasks/retrieval.py b/jiant/tasks/retrieval.py new file mode 100644 index 000000000..0da0eca45 --- /dev/null +++ b/jiant/tasks/retrieval.py @@ -0,0 +1,174 @@ +import os +from typing import Optional + +from jiant.tasks.lib.abductive_nli import AbductiveNliTask +from jiant.tasks.lib.acceptability_judgement.definiteness import AcceptabilityDefinitenessTask +from jiant.tasks.lib.adversarial_nli import AdversarialNliTask +from jiant.tasks.lib.boolq import BoolQTask +from jiant.tasks.lib.bucc2018 import Bucc2018Task +from jiant.tasks.lib.ccg import CCGTask +from jiant.tasks.lib.cola import ColaTask +from jiant.tasks.lib.commitmentbank import CommitmentBankTask +from jiant.tasks.lib.commonsenseqa import CommonsenseQATask +from jiant.tasks.lib.edge_probing.nonterminal import NonterminalTask +from jiant.tasks.lib.copa import CopaTask +from jiant.tasks.lib.edge_probing.coref import CorefTask +from jiant.tasks.lib.cosmosqa import CosmosQATask +from jiant.tasks.lib.edge_probing.dep import DepTask +from jiant.tasks.lib.edge_probing.dpr import DprTask +from jiant.tasks.lib.glue_diagnostics import GlueDiagnosticsTask +from jiant.tasks.lib.hellaswag import HellaSwagTask +from jiant.tasks.lib.mlm_simple import MLMSimpleTask +from jiant.tasks.lib.mlm_premasked import MLMPremaskedTask +from jiant.tasks.lib.mlm_pretokenized import MLMPretokenizedTask +from jiant.tasks.lib.mlqa import MlqaTask +from jiant.tasks.lib.mnli import MnliTask +from jiant.tasks.lib.mnli_mismatched import MnliMismatchedTask +from jiant.tasks.lib.mrpc import MrpcTask +from jiant.tasks.lib.multirc import MultiRCTask +from jiant.tasks.lib.edge_probing.ner import NerTask +from jiant.tasks.lib.panx import PanxTask +from jiant.tasks.lib.pawsx import PawsXTask +from jiant.tasks.lib.edge_probing.pos import PosTask +from jiant.tasks.lib.qamr import QAMRTask +from jiant.tasks.lib.qasrl import QASRLTask +from jiant.tasks.lib.qqp import QqpTask +from jiant.tasks.lib.qnli import QnliTask +from jiant.tasks.lib.record import ReCoRDTask +from jiant.tasks.lib.rte import RteTask +from jiant.tasks.lib.scitail import SciTailTask +from jiant.tasks.lib.senteval.tense import SentevalTenseTask +from jiant.tasks.lib.edge_probing.semeval import SemevalTask +from jiant.tasks.lib.snli import SnliTask +from jiant.tasks.lib.socialiqa import SocialIQATask +from jiant.tasks.lib.edge_probing.spr1 import Spr1Task +from jiant.tasks.lib.edge_probing.spr2 import Spr2Task +from jiant.tasks.lib.squad import SquadTask +from jiant.tasks.lib.edge_probing.srl import SrlTask +from jiant.tasks.lib.sst import SstTask +from jiant.tasks.lib.stsb import StsbTask +from jiant.tasks.lib.superglue_axg import SuperglueWinogenderDiagnosticsTask +from jiant.tasks.lib.superglue_axb import SuperglueBroadcoverageDiagnosticsTask +from jiant.tasks.lib.swag import SWAGTask +from jiant.tasks.lib.tatoeba import TatoebaTask +from jiant.tasks.lib.tydiqa import TyDiQATask +from jiant.tasks.lib.udpos import UdposTask +from jiant.tasks.lib.wic import WiCTask +from jiant.tasks.lib.wnli import WnliTask +from jiant.tasks.lib.wsc import WSCTask +from jiant.tasks.lib.xnli import XnliTask +from jiant.tasks.lib.xquad import XquadTask + +from jiant.tasks.core import Task +from jiant.utils.python.io import read_json + + +TASK_DICT = { + "abductive_nli": AbductiveNliTask, + "superglue_axg": SuperglueWinogenderDiagnosticsTask, + "acceptability_definiteness": AcceptabilityDefinitenessTask, + "adversarial_nli": AdversarialNliTask, + "boolq": BoolQTask, + "bucc2018": Bucc2018Task, + "cb": CommitmentBankTask, + "ccg": CCGTask, + "cola": ColaTask, + "commonsenseqa": CommonsenseQATask, + "nonterminal": NonterminalTask, + "copa": CopaTask, + "coref": CorefTask, + "cosmosqa": CosmosQATask, + "dep": DepTask, + "dpr": DprTask, + "glue_diagnostics": GlueDiagnosticsTask, + "hellaswag": HellaSwagTask, + "mlm_simple": MLMSimpleTask, + "mlm_premasked": MLMPremaskedTask, + "mlm_pretokenized": MLMPretokenizedTask, + "mlqa": MlqaTask, + "mnli": MnliTask, + "mnli_mismatched": MnliMismatchedTask, + "multirc": MultiRCTask, + "mrpc": MrpcTask, + "ner": NerTask, + "pawsx": PawsXTask, + "panx": PanxTask, + "pos": PosTask, + "qamr": QAMRTask, + "qasrl": QASRLTask, + "qnli": QnliTask, + "qqp": QqpTask, + "record": ReCoRDTask, + "rte": RteTask, + "scitail": SciTailTask, + "senteval_tense": SentevalTenseTask, + "semeval": SemevalTask, + "snli": SnliTask, + "socialiqa": SocialIQATask, + "spr1": Spr1Task, + "spr2": Spr2Task, + "squad": SquadTask, + "srl": SrlTask, + "sst": SstTask, + "stsb": StsbTask, + "superglue_axb": SuperglueBroadcoverageDiagnosticsTask, + "swag": SWAGTask, + "tatoeba": TatoebaTask, + "tydiqa": TyDiQATask, + "udpos": UdposTask, + "wic": WiCTask, + "wnli": WnliTask, + "wsc": WSCTask, + "xnli": XnliTask, + "xquad": XquadTask, +} + + +def get_task_class(task_name: str): + task_class = TASK_DICT[task_name] + assert issubclass(task_class, Task) + return task_class + + +def create_task_from_config(config: dict, base_path: Optional[str] = None, verbose: bool = False): + """Create task instance from task config. + + Args: + config (Dict): task config map. + base_path (str): if the path is not absolute, path is assumed to be relative to base_path. + verbose (bool): True if task config should be printed during task creation. + + Returns: + Task instance. + + """ + task_class = get_task_class(config["task"]) + for k in config["paths"].keys(): + path = config["paths"][k] + # TODO: Refactor paths (Issue #54) + if isinstance(path, str) and not os.path.isabs(path): + assert base_path + config["paths"][k] = os.path.join(base_path, path) + task_kwargs = config.get("kwargs", {}) + if verbose: + print(task_class.__name__) + for k, v in config["paths"].items(): + print(f" [{k}]: {v}") + # noinspection PyArgumentList + return task_class(name=config["name"], path_dict=config["paths"], **task_kwargs) + + +def create_task_from_config_path(config_path: str, verbose: bool = False): + """Creates task instance from task config filepath. + + Args: + config_path (str): config filepath. + verbose (bool): True if task config should be printed during task creation. + + Returns: + Task instance. + + """ + return create_task_from_config( + read_json(config_path), base_path=os.path.split(config_path)[0], verbose=verbose, + ) diff --git a/jiant/tasks/senteval_probing.py b/jiant/tasks/senteval_probing.py deleted file mode 100644 index b31e46c42..000000000 --- a/jiant/tasks/senteval_probing.py +++ /dev/null @@ -1,512 +0,0 @@ -""" -Set of probing tasks that were added to Senteval Probing. -Paper: https://arxiv.org/abs/1805.01070 -""" -import collections -import itertools -import json -import logging as log -import os - -import numpy as np -import pandas as pd -import torch - - -# Fields for instance processing -from jiant.utils.data_loaders import tokenize_and_truncate -from jiant.tasks.registry import register_task # global task registry -from jiant.tasks.tasks import SingleClassificationTask, process_single_pair_task_split - - -@register_task("se-probing-sentence-length", rel_path="sentence_length/") -class SEProbingSentenceLengthTask(SingleClassificationTask): - """ Sentence length task """ - - def __init__(self, path, max_seq_len, name, **kw): - super(SEProbingSentenceLengthTask, self).__init__(name, n_classes=7, **kw) - self.path = path - self.max_seq_len = max_seq_len - self._label_namespace = self.name + "_tags" - self.train_data_text = None - self.val_data_text = None - self.test_data_text = None - - def get_all_labels(self): - return [str(x) for x in list(range(6))] - - def get_sentences(self): - return self.sentences - - def load_data(self): - """ Load data """ - - def load_csv(data_file): - rows = pd.read_csv(data_file, encoding="utf-8") - rows = rows.sample(frac=1, axis=0).reset_index(drop=True) - rows["s1"] = rows["2"].apply( - lambda x: tokenize_and_truncate(self._tokenizer_name, x, self.max_seq_len) - ) - return rows["s1"].tolist(), [], rows["1"].tolist(), list(range(len(rows))) - - self.train_data_text = load_csv(os.path.join(self.path, "train.csv")) - self.val_data_text = load_csv(os.path.join(self.path, "val.csv")) - self.test_data_text = load_csv(os.path.join(self.path, "test.csv")) - - sentences = [] - for split in ["train", "val", "test"]: - split_data = getattr(self, "%s_data_text" % split) - sentences.extend(split_data[0]) - self.sentences = sentences - - -@register_task("se-probing-bigram-shift", rel_path="bigram_shift/") -class SEProbingBigramShiftTask(SingleClassificationTask): - """ Bigram shift task """ - - def __init__(self, path, max_seq_len, name, **kw): - super(SEProbingBigramShiftTask, self).__init__(name, n_classes=2, **kw) - self.path = path - self.max_seq_len = max_seq_len - self._label_namespace = self.name + "_tags" - self.train_data_text = None - self.val_data_text = None - self.test_data_text = None - - def get_all_labels(self): - return ["I", "O"] - - def get_sentences(self): - return self.sentences - - def process_split(self, split, indexers, model_preprocessing_interface): - return process_single_pair_task_split( - split, - indexers, - model_preprocessing_interface, - label_namespace=self._label_namespace, - is_pair=False, - skip_indexing=False, - ) - - def load_data(self): - """ Load data """ - - def load_csv(data_file): - rows = pd.read_csv(data_file, encoding="utf-8") - rows["s1"] = rows["2"].apply( - lambda x: tokenize_and_truncate(self._tokenizer_name, x, self.max_seq_len) - ) - return rows["s1"].tolist(), [], rows["1"].tolist(), list(range(len(rows))) - - self.train_data_text = load_csv(os.path.join(self.path, "train.csv")) - self.val_data_text = load_csv(os.path.join(self.path, "val.csv")) - self.test_data_text = load_csv(os.path.join(self.path, "test.csv")) - - sentences = [] - for split in ["train", "val", "test"]: - split_data = getattr(self, "%s_data_text" % split) - sentences.extend(split_data[0]) - self.sentences = sentences - - -@register_task("se-probing-past-present", rel_path="past_present/") -class SEProbingPastPresentTask(SingleClassificationTask): - """ Past Present Task """ - - def __init__(self, path, max_seq_len, name, **kw): - super(SEProbingPastPresentTask, self).__init__(name, n_classes=2, **kw) - self.path = path - self.max_seq_len = max_seq_len - self._label_namespace = self.name + "_tags" - self.train_data_text = None - self.val_data_text = None - self.test_data_text = None - - def get_all_labels(self): - return ["PAST", "PRES"] - - def get_sentences(self): - return self.sentences - - def process_split(self, split, indexers, model_preprocessing_interface): - return process_single_pair_task_split( - split, - indexers, - model_preprocessing_interface, - label_namespace=self._label_namespace, - is_pair=False, - skip_indexing=False, - ) - - def load_data(self): - """ Load data """ - - def load_csv(data_file): - rows = pd.read_csv(data_file, encoding="utf-8") - rows["s1"] = rows["2"].apply( - lambda x: tokenize_and_truncate(self._tokenizer_name, x, self.max_seq_len) - ) - return rows["s1"].tolist(), [], rows["1"].tolist(), list(range(len(rows))) - - self.train_data_text = load_csv(os.path.join(self.path, "train.csv")) - self.val_data_text = load_csv(os.path.join(self.path, "val.csv")) - self.test_data_text = load_csv(os.path.join(self.path, "test.csv")) - - sentences = [] - for split in ["train", "val", "test"]: - split_data = getattr(self, "%s_data_text" % split) - sentences.extend(split_data[0]) - self.sentences = sentences - - -@register_task("se-probing-odd-man-out", rel_path="odd_man_out/") -class SEProbingOddManOutTask(SingleClassificationTask): - """ Odd man out task """ - - def __init__(self, path, max_seq_len, name, **kw): - super(SEProbingOddManOutTask, self).__init__(name, n_classes=2, **kw) - self.path = path - self.max_seq_len = max_seq_len - self._label_namespace = self.name + "_tags" - self.train_data_text = None - self.val_data_text = None - self.test_data_text = None - - def get_all_labels(self): - return ["C", "O"] - - def process_split(self, split, indexers, model_preprocessing_interface): - return process_single_pair_task_split( - split, - indexers, - model_preprocessing_interface, - label_namespace=self._label_namespace, - is_pair=False, - skip_indexing=False, - ) - - def get_sentences(self): - return self.sentences - - def load_data(self): - """ Load data """ - - def load_csv(data_file): - rows = pd.read_csv(data_file, encoding="utf-8") - rows["s1"] = rows["2"].apply( - lambda x: tokenize_and_truncate(self._tokenizer_name, x, self.max_seq_len) - ) - return rows["s1"].tolist(), [], rows["1"].tolist(), list(range(len(rows))) - - self.train_data_text = load_csv(os.path.join(self.path, "train.csv")) - self.val_data_text = load_csv(os.path.join(self.path, "val.csv")) - self.test_data_text = load_csv(os.path.join(self.path, "test.csv")) - - sentences = [] - for split in ["train", "val", "test"]: - split_data = getattr(self, "%s_data_text" % split) - sentences.extend(split_data[0]) - self.sentences = sentences - - -@register_task("se-probing-coordination-inversion", rel_path="coordination_inversion/") -class SEProbingCoordinationInversionTask(SingleClassificationTask): - """ Coordination Inversion task. """ - - def __init__(self, path, max_seq_len, name, **kw): - super(SEProbingCoordinationInversionTask, self).__init__(name, n_classes=2, **kw) - self.path = path - self.max_seq_len = max_seq_len - self._label_namespace = self.name + "_tags" - self.train_data_text = None - self.val_data_text = None - self.test_data_text = None - - def get_all_labels(self): - return ["O", "I"] - - def get_sentences(self): - return self.sentences - - def process_split(self, split, indexers, model_preprocessing_interface): - return process_single_pair_task_split( - split, - indexers, - model_preprocessing_interface, - label_namespace=self._label_namespace, - is_pair=False, - skip_indexing=False, - ) - - def load_data(self): - """ Load data """ - - def load_csv(data_file): - rows = pd.read_csv(data_file, encoding="utf-8") - rows["s1"] = rows["2"].apply( - lambda x: tokenize_and_truncate(self._tokenizer_name, x, self.max_seq_len) - ) - return rows["s1"].tolist(), [], rows["1"].tolist(), list(range(len(rows))) - - self.train_data_text = load_csv(os.path.join(self.path, "train.csv")) - self.val_data_text = load_csv(os.path.join(self.path, "val.csv")) - self.test_data_text = load_csv(os.path.join(self.path, "test.csv")) - - sentences = [] - for split in ["train", "val", "test"]: - split_data = getattr(self, "%s_data_text" % split) - sentences.extend(split_data[0]) - self.sentences = sentences - - -@register_task("se-probing-word-content", rel_path="word_content") -class SEProbingWordContentTask(SingleClassificationTask): - """ Word Content Task """ - - def __init__(self, path, max_seq_len, name, **kw): - super(SEProbingWordContentTask, self).__init__(name, n_classes=1000, **kw) - self.path = path - self.max_seq_len = max_seq_len - self._label_namespace = self.name + "_tags" - self.train_data_text = None - self.val_data_text = None - self.test_data_text = None - self.labels = [] - - def get_all_labels(self): - return list(set(self.labels)) - - def get_sentences(self): - return self.sentences - - def process_split(self, split, indexers, model_preprocessing_interface): - return process_single_pair_task_split( - split, - indexers, - model_preprocessing_interface, - label_namespace=self._label_namespace, - is_pair=False, - skip_indexing=False, - ) - - def load_data(self): - """ Load data """ - - def load_csv(data_file): - rows = pd.read_csv(data_file, encoding="utf-8") - labels = rows["1"].apply(lambda x: x.split("\t")[0]) - s1 = rows["1"].apply(lambda x: x.split("\t")[1]) - s1 = s1.apply( - lambda x: tokenize_and_truncate(self._tokenizer_name, x, self.max_seq_len) - ) - self.labels = list(set(labels.tolist())) - return s1.tolist(), [], labels.tolist(), list(range(len(rows))) - - self.train_data_text = load_csv(os.path.join(self.path, "train.csv")) - self.val_data_text = load_csv(os.path.join(self.path, "val.csv")) - self.test_data_text = load_csv(os.path.join(self.path, "test.csv")) - sentences = [] - for split in ["train", "val", "test"]: - split_data = getattr(self, "%s_data_text" % split) - sentences.extend(split_data[0]) - self.sentences = sentences - - -@register_task("se-probing-tree-depth", rel_path="tree_depth") -class SEProbingTreeDepthTask(SingleClassificationTask): - """ Tree Depth Task """ - - def __init__(self, path, max_seq_len, name, **kw): - super(SEProbingTreeDepthTask, self).__init__(name, n_classes=8, **kw) - self.path = path - self.max_seq_len = max_seq_len - self._label_namespace = self.name + "_tags" - self.train_data_text = None - self.val_data_text = None - self.test_data_text = None - - def get_all_labels(self): - return [str(x) for x in list(range(8))] - - def get_sentences(self): - return self.sentences - - def load_data(self): - """ Load data """ - - def load_csv(data_file): - rows = pd.read_csv(data_file, encoding="utf-8") - labels = rows["1"].apply(lambda x: int(x.split("\t")[0])) - labels = labels.apply(lambda x: x - 5) - s1 = rows["1"].apply(lambda x: x.split("\t")[1]) - s1 = s1.apply( - lambda x: tokenize_and_truncate(self._tokenizer_name, x, self.max_seq_len) - ) - return s1.tolist(), [], labels.tolist(), list(range(len(rows))) - - self.train_data_text = load_csv(os.path.join(self.path, "train.csv")) - self.val_data_text = load_csv(os.path.join(self.path, "val.csv")) - self.test_data_text = load_csv(os.path.join(self.path, "test.csv")) - sentences = [] - for split in ["train", "val", "test"]: - split_data = getattr(self, "%s_data_text" % split) - sentences.extend(split_data[0]) - self.sentences = sentences - - -@register_task("se-probing-top-constituents", rel_path="top_constituents/") -class SEProbingTopConstituentsTask(SingleClassificationTask): - """ Top Constituents task """ - - def __init__(self, path, max_seq_len, name, **kw): - super(SEProbingTopConstituentsTask, self).__init__(name, n_classes=20, **kw) - self.path = path - self.max_seq_len = max_seq_len - self._label_namespace = self.name + "_tags" - self.train_data_text = None - self.val_data_text = None - self.test_data_text = None - - def get_all_labels(self): - return self.labels - - def process_split(self, split, indexers, model_preprocessing_interface): - return process_single_pair_task_split( - split, - indexers, - model_preprocessing_interface, - label_namespace=self._label_namespace, - is_pair=False, - skip_indexing=False, - ) - - def get_sentences(self): - return self.sentences - - def load_data(self): - """ Load data """ - - def load_csv(data_file): - rows = pd.read_csv(data_file, encoding="utf-8") - labels = rows["1"].apply(lambda x: str(x.split("\t")[0])) - self.labels = list(set(labels.tolist())) - s1 = rows["1"].apply(lambda x: x.split("\t")[1]) - s1 = s1.apply( - lambda x: tokenize_and_truncate(self._tokenizer_name, x, self.max_seq_len) - ) - return s1.tolist(), [], labels.tolist(), list(range(len(rows))) - - self.train_data_text = load_csv(os.path.join(self.path, "train.csv")) - self.val_data_text = load_csv(os.path.join(self.path, "val.csv")) - self.test_data_text = load_csv(os.path.join(self.path, "test.csv")) - - sentences = [] - for split in ["train", "val", "test"]: - split_data = getattr(self, "%s_data_text" % split) - sentences.extend(split_data[0]) - self.sentences = sentences - - -@register_task("se-probing-subj-number", rel_path="subj_number") -class SEProbingSubjNumberTask(SingleClassificationTask): - """ Subject number task """ - - def __init__(self, path, max_seq_len, name, **kw): - super(SEProbingSubjNumberTask, self).__init__(name, n_classes=2, **kw) - self.path = path - self.max_seq_len = max_seq_len - self._label_namespace = self.name + "_tags" - self.train_data_text = None - self.val_data_text = None - self.test_data_text = None - - def get_all_labels(self): - return ["NN", "NNS"] - - def process_split(self, split, indexers, model_preprocessing_interface): - return process_single_pair_task_split( - split, - indexers, - model_preprocessing_interface, - label_namespace=self._label_namespace, - is_pair=False, - skip_indexing=False, - ) - - def get_sentences(self): - return self.sentences - - def load_data(self): - """ Load data """ - - def load_csv(data_file): - rows = pd.read_csv(data_file, encoding="utf-8") - labels = rows["1"].apply(lambda x: str(x.split("\t")[0])) - s1 = rows["1"].apply(lambda x: x.split("\t")[1]) - s1 = s1.apply( - lambda x: tokenize_and_truncate(self._tokenizer_name, x, self.max_seq_len) - ) - return s1.tolist(), [], labels.tolist(), list(range(len(rows))) - - self.train_data_text = load_csv(os.path.join(self.path, "train.csv")) - self.val_data_text = load_csv(os.path.join(self.path, "val.csv")) - self.test_data_text = load_csv(os.path.join(self.path, "test.csv")) - - sentences = [] - for split in ["train", "val", "test"]: - split_data = getattr(self, "%s_data_text" % split) - sentences.extend(split_data[0]) - self.sentences = sentences - - -@register_task("se-probing-obj-number", rel_path="obj_number") -class SEProbingObjNumberTask(SingleClassificationTask): - """ Object number task """ - - def __init__(self, path, max_seq_len, name, **kw): - super(SEProbingObjNumberTask, self).__init__(name, n_classes=2, **kw) - self.path = path - self.max_seq_len = max_seq_len - self._label_namespace = self.name + "_tags" - self.train_data_text = None - self.val_data_text = None - self.test_data_text = None - - def get_all_labels(self): - return ["NN", "NNS"] - - def process_split(self, split, indexers, model_preprocessing_interface): - return process_single_pair_task_split( - split, - indexers, - model_preprocessing_interface, - label_namespace=self._label_namespace, - is_pair=False, - skip_indexing=False, - ) - - def get_sentences(self): - return self.sentences - - def load_data(self): - """ Load data """ - - def load_csv(data_file): - rows = pd.read_csv(data_file, encoding="utf-8") - labels = rows["1"].apply(lambda x: str(x.split("\t")[0])) - s1 = rows["1"].apply(lambda x: x.split("\t")[1]) - s1 = s1.apply( - lambda x: tokenize_and_truncate(self._tokenizer_name, x, self.max_seq_len) - ) - return s1.tolist(), [], labels.tolist(), list(range(len(rows))) - - self.train_data_text = load_csv(os.path.join(self.path, "train.csv")) - self.val_data_text = load_csv(os.path.join(self.path, "val.csv")) - self.test_data_text = load_csv(os.path.join(self.path, "test.csv")) - - sentences = [] - for split in ["train", "val", "test"]: - split_data = getattr(self, "%s_data_text" % split) - sentences.extend(split_data[0]) - self.sentences = sentences diff --git a/jiant/tasks/seq2seq.py b/jiant/tasks/seq2seq.py deleted file mode 100644 index 662946d9e..000000000 --- a/jiant/tasks/seq2seq.py +++ /dev/null @@ -1,147 +0,0 @@ -"""Task definitions for sequence-to-sequence tasks.""" -import codecs -import collections -import math -import os -from typing import Iterable, List, Sequence, Type - -from allennlp.data import Instance -from allennlp.data.token_indexers import SingleIdTokenIndexer -from allennlp.training.metrics import Average, BooleanAccuracy - -from jiant.utils.tokenizers import get_tokenizer -from ..utils.data_loaders import tokenize_and_truncate -from .registry import register_task -from .tasks import ( - UNK_TOK_ALLENNLP, - UNK_TOK_ATOMIC, - SequenceGenerationTask, - atomic_tokenize, - sentence_to_text_field, -) - - -@register_task("seg-wix", rel_path="seg/wix/", max_targ_v_size=200) -class Seq2SeqTask(SequenceGenerationTask): - """Sequence-to-sequence Task""" - - def __init__(self, path, max_seq_len, max_targ_v_size, name, **kw): - super().__init__(name, **kw) - self.scorer2 = BooleanAccuracy() - self.scorers.append(self.scorer2) - self.val_metric = "%s_accuracy" % self.name - self.val_metric_decreases = False - self.max_seq_len = max_seq_len - self._label_namespace = self.name + "_tokens" - self.max_targ_v_size = max_targ_v_size - self.target_indexer = {"words": SingleIdTokenIndexer(namespace=self._label_namespace)} - self.files_by_split = { - split: os.path.join(path, "%s.tsv" % split) for split in ["train", "val", "test"] - } - - # The following is necessary since word-level tasks (e.g., MT) haven't been tested, yet. - if self._tokenizer_name != "SplitChars" and self._tokenizer_name != "dummy_tokenizer_name": - raise NotImplementedError("For now, Seq2SeqTask only supports character-level tasks.") - - def load_data(self): - # Data is exposed as iterable: no preloading - pass - - def get_split_text(self, split: str): - """ - Get split text as iterable of records. - Split should be one of 'train', 'val', or 'test'. - """ - return self.get_data_iter(self.files_by_split[split]) - - def get_all_labels(self) -> List[str]: - """ Build character vocabulary and return it as a list """ - token2freq = collections.Counter() - for split in ["train", "val"]: - for _, sequence in self.get_data_iter(self.files_by_split[split]): - for token in sequence: - token2freq[token] += 1 - return [t for t, _ in token2freq.most_common(self.max_targ_v_size)] - - def get_data_iter(self, path): - """ Load data """ - with codecs.open(path, "r", "utf-8", errors="ignore") as txt_fh: - for row in txt_fh: - row = row.strip().split("\t") - if len(row) < 2 or not row[0] or not row[1]: - continue - src_sent = tokenize_and_truncate(self._tokenizer_name, row[0], self.max_seq_len) - tgt_sent = tokenize_and_truncate(self._tokenizer_name, row[2], self.max_seq_len) - yield (src_sent, tgt_sent) - - def get_sentences(self) -> Iterable[Sequence[str]]: - """ Yield sentences, used to compute vocabulary. """ - for split in self.files_by_split: - # Don't use test set for vocab building. - if split.startswith("test"): - continue - path = self.files_by_split[split] - yield from self.get_data_iter(path) - - def count_examples(self): - """ Compute here b/c we're streaming the sentences. """ - example_counts = {} - for split, split_path in self.files_by_split.items(): - example_counts[split] = sum( - 1 for _ in codecs.open(split_path, "r", "utf-8", errors="ignore") - ) - self.example_counts = example_counts - - def process_split( - self, split, indexers, model_preprocessing_interface - ) -> Iterable[Type[Instance]]: - """ Process split text into a list of AllenNLP Instances. """ - - def _make_instance(input_, target): - d = { - "inputs": sentence_to_text_field( - model_preprocessing_interface.boundary_token_fn(input_), indexers - ), - "targs": sentence_to_text_field( - model_preprocessing_interface.boundary_token_fn(target), self.target_indexer - ), - } - return Instance(d) - - for sent1, sent2 in split: - yield _make_instance(sent1, sent2) - - def get_metrics(self, reset=False): - """Get metrics specific to the task""" - avg_nll = self.scorer1.get_metric(reset) - acc = self.scorer2.get_metric(reset) - return {"perplexity": math.exp(avg_nll), "accuracy": acc} - - def update_metrics(self, logits, labels, tagmask=None, predictions=None): - # This doesn't require logits for now, since loss is updated in another part. - assert logits is None and predictions is not None - - if labels.shape[1] < predictions.shape[2]: - predictions = predictions[:, 0, : labels.shape[1]] - else: - predictions = predictions[:, 0, :] - # Cut labels if predictions (without gold target) are shorter. - labels = labels[:, : predictions.shape[1]] - tagmask = tagmask[:, : predictions.shape[1]] - self.scorer2(predictions, labels, tagmask) - return - - def get_prediction(self, voc_src, voc_trg, inputs, gold, output): - tokenizer = get_tokenizer(self._tokenizer_name) - - input_string = tokenizer.detokenize([voc_src[token.item()] for token in inputs]).split( - "" - )[0] - gold_string = tokenizer.detokenize([voc_trg[token.item()] for token in gold]).split( - "" - )[0] - output_string = tokenizer.detokenize([voc_trg[token.item()] for token in output]).split( - "" - )[0] - - return input_string, gold_string, output_string diff --git a/jiant/tasks/tasks.py b/jiant/tasks/tasks.py deleted file mode 100644 index 7f3723900..000000000 --- a/jiant/tasks/tasks.py +++ /dev/null @@ -1,3940 +0,0 @@ -import collections -import itertools -import json -import logging as log -import os -from typing import Any, Dict, Iterable, List, Sequence, Type, Union, Generator -import random - -import numpy as np -import pandas as pd -import torch - - -# Fields for instance processing -from allennlp.data import Instance, Token, vocabulary -from allennlp.data.fields import ( - LabelField, - ListField, - MetadataField, - MultiLabelField, - SpanField, - TextField, -) -from allennlp.data.token_indexers import SingleIdTokenIndexer -from allennlp.training.metrics import Average, BooleanAccuracy, CategoricalAccuracy, F1Measure -from sklearn.metrics import mean_squared_error - -from jiant.allennlp_mods.correlation import Correlation -from jiant.allennlp_mods.numeric_field import NumericField -from jiant.utils import utils -from jiant.utils.data_loaders import ( - get_tag_list, - load_diagnostic_tsv, - load_span_data, - load_tsv, - tokenize_and_truncate, - load_pair_nli_jsonl, -) -from jiant.utils.serialize import RepeatableIterator -from jiant.utils.tokenizers import get_tokenizer -from jiant.utils.retokenize import get_aligner_fn -from jiant.tasks.registry import register_task # global task registry -from jiant.metrics.winogender_metrics import GenderParity -from jiant.metrics.nli_metrics import NLITwoClassAccuracy - -"""Define the tasks and code for loading their data. - -- As much as possible, following the existing task hierarchy structure. -- When inheriting, be sure to write and call load_data. -- Set all text data as an attribute, task.sentences (List[List[str]]) -- Each task's val_metric should be name_metric, where metric is returned by -get_metrics(): e.g. if task.val_metric = task_name + "_accuracy", then -task.get_metrics() should return {"accuracy": accuracy_val, ... } -""" - - -UNK_TOK_ALLENNLP = "@@UNKNOWN@@" -UNK_TOK_ATOMIC = "UNKNOWN" # an unk token that won't get split by tokenizers - - -def sentence_to_text_field(sent: Sequence[str], indexers: Any): - """ Helper function to map a sequence of tokens into a sequence of - AllenNLP Tokens, then wrap in a TextField with the given indexers """ - return TextField(list(map(Token, sent)), token_indexers=indexers) - - -def atomic_tokenize( - sent: str, atomic_tok: str, nonatomic_toks: List[str], max_seq_len: int, tokenizer_name: str -): - """ Replace tokens that will be split by tokenizer with a - placeholder token. Tokenize, and then substitute the placeholder - with the *first* nonatomic token in the list. """ - for nonatomic_tok in nonatomic_toks: - sent = sent.replace(nonatomic_tok, atomic_tok) - sent = tokenize_and_truncate(tokenizer_name, sent, max_seq_len) - sent = [nonatomic_toks[0] if t == atomic_tok else t for t in sent] - return sent - - -def process_single_pair_task_split( - split, - indexers, - model_preprocessing_interface, - is_pair=True, - classification=True, - label_namespace="labels", - is_symmetrical_pair=False, - skip_indexing=True, -): - """ - Convert a dataset of sentences into padded sequences of indices. Shared - across several classes. - - Args: - - split (list[list[str]]): list of inputs (possibly pair) and outputs - - indexers () - - model_preprocessing_interface: packed information from model that effects the task data - - is_pair (Bool) - - classification (Bool) - - is_symmetrical_pair (Bool) whether reverse the sentences in a pair will change the result, - if this is true, and the model allows uses_mirrored_pair, a mirrored pair will be added - to the input - - Returns: - - instances (Iterable[Instance]): an iterable of AllenNLP Instances with fields - """ - # check here if using bert to avoid passing model info to tasks - - def _make_instance(input1, input2, labels, idx): - d = {} - d["sent1_str"] = MetadataField(" ".join(input1)) - if model_preprocessing_interface.model_flags["uses_pair_embedding"] and is_pair: - inp = model_preprocessing_interface.boundary_token_fn(input1, input2) - d["inputs"] = sentence_to_text_field(inp, indexers) - d["sent2_str"] = MetadataField(" ".join(input2)) - if ( - model_preprocessing_interface.model_flags["uses_mirrored_pair"] - and is_symmetrical_pair - ): - inp_m = model_preprocessing_interface.boundary_token_fn(input2, input1) - d["inputs_m"] = sentence_to_text_field(inp_m, indexers) - else: - d["input1"] = sentence_to_text_field( - model_preprocessing_interface.boundary_token_fn(input1), indexers - ) - if input2: - d["input2"] = sentence_to_text_field( - model_preprocessing_interface.boundary_token_fn(input2), indexers - ) - d["sent2_str"] = MetadataField(" ".join(input2)) - if classification: - d["labels"] = LabelField( - labels, label_namespace=label_namespace, skip_indexing=skip_indexing - ) - else: - d["labels"] = NumericField(labels) - - d["idx"] = LabelField(idx, label_namespace="idxs_tags", skip_indexing=True) - - return Instance(d) - - split = list(split) - if not is_pair: # dummy iterator for input2 - split[1] = itertools.repeat(None) - if len(split) < 4: # counting iterator for idx - assert len(split) == 3 - split.append(itertools.count()) - - # Map over columns: input1, (input2), labels, idx - instances = map(_make_instance, *split) - return instances # lazy iterator - - -def create_subset_scorers(count, scorer_type, **args_to_scorer): - """ - Create a list scorers of designated type for each "coarse__fine" tag. - This function is only used by tasks that need evalute results on tags, - and should be called after loading all the splits. - - Parameters: - count: N_tag, number of different "coarse__fine" tags - scorer_type: which scorer to use - **args_to_scorer: arguments passed to the scorer - Returns: - scorer_list: a list of N_tag scorer object - """ - scorer_list = [scorer_type(**args_to_scorer) for _ in range(count)] - return scorer_list - - -def update_subset_scorers(scorer_list, estimations, labels, tagmask): - """ - Add the output and label of one minibatch to the subset scorer objects. - This function is only used by tasks that need evalute results on tags, - and should be called every minibatch when task.scorer are updated. - - Parameters: - scorer_list: a list of N_tag scorer object - estimations: a (bs, *) tensor, model estimation - labels: a (bs, *) tensor, ground truth - tagmask: a (bs, N_tag) 0-1 tensor, indicating tags of each sample - """ - for tid, scorer in enumerate(scorer_list): - subset_idx = torch.nonzero(tagmask[:, tid]).squeeze(dim=1) - subset_estimations = estimations[subset_idx] - subset_labels = labels[subset_idx] - if len(subset_idx) > 0: - scorer(subset_estimations, subset_labels) - return - - -def collect_subset_scores(scorer_list, metric_name, tag_list, reset=False): - """ - Get the scorer measures of each tag. - This function is only used by tasks that need evalute results on tags, - and should be called in get_metrics. - - Parameters: - scorer_list: a list of N_tag scorer object - metric_name: string, name prefix for this group - tag_list: "coarse__fine" tag strings - Returns: - subset_scores: a dictionary from subset tags to scores - reset: - """ - subset_scores = { - "%s_%s" % (metric_name, tag_str): scorer.get_metric(reset) - for tag_str, scorer in zip(tag_list, scorer_list) - } - return subset_scores - - -class Task(object): - """Generic class for a task - - Methods and attributes: - - load_data: load dataset from a path and create splits - - get_metrics: - - Outside the task: - - process: pad and indexify data given a mapping - - optimizer - """ - - def __init__(self, name, tokenizer_name): - self.name = name - self._tokenizer_name = tokenizer_name - self.scorers = [] - self.eval_only_task = False - self.sentences = None - self.example_counts = None - self.contributes_to_aggregate_score = True - self._instance_iterables = {} - - def load_data(self): - """ Load data from path and create splits. """ - raise NotImplementedError - - def get_sentences(self) -> Iterable[Sequence[str]]: - """ Yield sentences, used to compute vocabulary. """ - yield from self.sentences - - def count_examples(self, splits=["train", "val", "test"]): - """ Count examples in the dataset. """ - self.example_counts = {} - for split in splits: - st = self.get_split_text(split) - count = self.get_num_examples(st) - self.example_counts[split] = count - - @property - def tokenizer_name(self): - return self._tokenizer_name - - @property - def n_train_examples(self): - return self.example_counts["train"] - - @property - def n_val_examples(self): - return self.example_counts["val"] - - def get_split_text(self, split: str): - """ Get split text, typically as list of columns. - - Split should be one of 'train', 'val', or 'test'. - """ - return getattr(self, "%s_data_text" % split) - - def get_num_examples(self, split_text): - """ Return number of examples in the result of get_split_text. - - Subclass can override this if data is not stored in column format. - """ - return len(split_text[0]) - - def process_split( - self, split, indexers, model_preprocessing_interface - ) -> Iterable[Type[Instance]]: - """ Process split text into a list of AllenNLP Instances. """ - raise NotImplementedError - - def get_metrics(self, reset: bool = False) -> Dict: - """ Get metrics specific to the task. """ - raise NotImplementedError - - def get_scorers(self): - return self.scorers - - def update_metrics(self, out, batch): - raise NotImplementedError - - def handle_preds(self, preds, batch): - """ - Function that does task-specific processing of predictions. - """ - return preds - - def set_instance_iterable( - self, split_name: str, instance_iterable: Iterable, phase: str = None - ): - """Takes a data instance iterable and stores it in a private field of this Task instance - - Parameters - ---------- - split_name : string - instance_iterable : Iterable - phase : str - - """ - self._instance_iterables[(split_name, phase)] = instance_iterable - - def get_instance_iterable( - self, split_name: str, phase: str = None - ) -> Union[RepeatableIterator, Generator]: - """Returns an instance iterable for the specified split name and phase. - - Parameters - ---------- - split_name : string - phase : string - - Returns - ------- - Union[RepeatableIterator, Generator] - - """ - if not self._instance_iterables: - raise ValueError("set_instance_iterable must be called before get_instance_iterable") - if split_name == "train" and phase is None: - raise ValueError("phase must be specified to get relevant training data") - return self._instance_iterables[(split_name, phase)] - - -class ClassificationTask(Task): - """ General classification task """ - - pass - - -class RegressionTask(Task): - """ General regression task """ - - pass - - -class SingleClassificationTask(ClassificationTask): - """ Generic sentence pair classification """ - - def __init__(self, name, n_classes, **kw): - super().__init__(name, **kw) - self.n_classes = n_classes - self.scorer1 = CategoricalAccuracy() - self.scorers = [self.scorer1] - self.val_metric = "%s_accuracy" % self.name - self.val_metric_decreases = False - - def get_metrics(self, reset=False): - """Get metrics specific to the task""" - acc = self.scorer1.get_metric(reset) - return {"accuracy": acc} - - def process_split( - self, split, indexers, model_preprocessing_interface - ) -> Iterable[Type[Instance]]: - """ Process split text into a list of AllenNLP Instances. """ - return process_single_pair_task_split( - split, indexers, model_preprocessing_interface, is_pair=False - ) - - def update_metrics(self, out, batch): - logits = out["logits"] - labels = out["labels"] - assert len(self.get_scorers()) > 0, "Please specify a score metric" - for scorer in self.get_scorers(): - scorer(logits, labels) - - -class PairClassificationTask(ClassificationTask): - """ Generic sentence pair classification """ - - def __init__(self, name, n_classes, **kw): - super().__init__(name, **kw) - assert n_classes > 0 - self.n_classes = n_classes - self.scorer1 = CategoricalAccuracy() - self.scorers = [self.scorer1] - self.val_metric = "%s_accuracy" % self.name - self.val_metric_decreases = False - - def get_metrics(self, reset=False): - """Get metrics specific to the task""" - acc = self.scorer1.get_metric(reset) - return {"accuracy": acc} - - def process_split( - self, split, indexers, model_preprocessing_interface - ) -> Iterable[Type[Instance]]: - """ Process split text into a list of AllenNLP Instances. """ - return process_single_pair_task_split( - split, indexers, model_preprocessing_interface, is_pair=True - ) - - def update_metrics(self, out, batch): - logits = out["logits"] - labels = out["labels"] - assert len(self.get_scorers()) > 0, "Please specify a score metric" - for scorer in self.get_scorers(): - scorer(logits, labels) - - -class PairRegressionTask(RegressionTask): - """ Generic sentence pair classification """ - - def __init__(self, name, **kw): - super().__init__(name, **kw) - self.n_classes = 1 - self.scorer1 = Average() # for average MSE - self.scorers = [self.scorer1] - self.val_metric = "%s_mse" % self.name - self.val_metric_decreases = True - - def get_metrics(self, reset=False): - """Get metrics specific to the task""" - mse = self.scorer1.get_metric(reset) - return {"mse": mse} - - def process_split( - self, split, indexers, model_preprocessing_interface - ) -> Iterable[Type[Instance]]: - """ Process split text into a list of AllenNLP Instances. """ - return process_single_pair_task_split( - split, indexers, model_preprocessing_interface, is_pair=True, classification=False - ) - - def update_metrics(self, out, batch): - logits = out["logits"] - labels = out["labels"] - assert len(self.get_scorers()) > 0, "Please specify a score metric" - for scorer in self.get_scorers(): - scorer(logits, labels) - - -class PairOrdinalRegressionTask(RegressionTask): - """ Generic sentence pair ordinal regression. - Currently just doing regression but added new class - in case we find a good way to implement ordinal regression with NN""" - - def __init__(self, name, **kw): - super().__init__(name, **kw) - self.n_classes = 1 - self.scorer1 = Average() # for average MSE - self.scorer2 = Correlation("spearman") - self.scorers = [self.scorer1, self.scorer2] - self.val_metric = "%s_1-mse" % self.name - self.val_metric_decreases = False - - def get_metrics(self, reset=False): - mse = self.scorer1.get_metric(reset) - spearmanr = self.scorer2.get_metric(reset) - return {"1-mse": 1 - mse, "mse": mse, "spearmanr": spearmanr} - - def process_split( - self, split, indexers, model_preprocessing_interface - ) -> Iterable[Type[Instance]]: - """ Process split text into a list of AllenNLP Instances. """ - return process_single_pair_task_split( - split, indexers, model_preprocessing_interface, is_pair=True, classification=False - ) - - def update_metrics(self, out, batch): - logits = out["logits"] - labels = out["labels"] - assert len(self.get_scorers()) > 0, "Please specify a score metric" - for scorer in self.get_scorers(): - scorer(logits, labels) - - -class SequenceGenerationTask(Task): - """ Generic sentence generation task """ - - def __init__(self, name, **kw): - super().__init__(name, **kw) - self.scorer1 = Average() # for average BLEU or something - self.scorers = [self.scorer1] - self.val_metric = "%s_bleu" % self.name - self.val_metric_decreases = False - log.warning( - "BLEU scoring is turned off (current code in progress)." - "Please use outputed prediction files to score offline" - ) - - def get_metrics(self, reset=False): - """Get metrics specific to the task""" - bleu = self.scorer1.get_metric(reset) - return {"bleu": bleu} - - def update_metrics(self, out, batch): - # currently don't support metrics for regression task - # TODO(Yada): support them! - return - - -class RankingTask(Task): - """ Generic sentence ranking task, given some input """ - - pass - - -@register_task("sst", rel_path="SST-2/") -class SSTTask(SingleClassificationTask): - """ Task class for Stanford Sentiment Treebank. """ - - def __init__(self, path, max_seq_len, name, **kw): - super(SSTTask, self).__init__(name, n_classes=2, **kw) - self.path = path - self.max_seq_len = max_seq_len - - self.train_data_text = None - self.val_data_text = None - self.test_data_text = None - - def load_data(self): - """ Load data """ - self.train_data_text = load_tsv( - self._tokenizer_name, - os.path.join(self.path, "train.tsv"), - max_seq_len=self.max_seq_len, - s1_idx=0, - s2_idx=None, - label_idx=1, - skip_rows=1, - ) - self.val_data_text = load_tsv( - self._tokenizer_name, - os.path.join(self.path, "dev.tsv"), - max_seq_len=self.max_seq_len, - s1_idx=0, - s2_idx=None, - label_idx=1, - skip_rows=1, - ) - self.test_data_text = load_tsv( - self._tokenizer_name, - os.path.join(self.path, "test.tsv"), - max_seq_len=self.max_seq_len, - s1_idx=1, - s2_idx=None, - has_labels=False, - return_indices=True, - skip_rows=1, - ) - self.sentences = self.train_data_text[0] + self.val_data_text[0] - log.info("\tFinished loading SST data.") - - -@register_task("npi-adv-li", rel_path="NPI/probing/adverbs/licensor") -@register_task("npi-adv-sc", rel_path="NPI/probing/adverbs/scope_with_licensor") -@register_task("npi-adv-pr", rel_path="NPI/probing/adverbs/npi_present") -@register_task("npi-cond-li", rel_path="NPI/probing/conditionals/licensor") -@register_task("npi-cond-sc", rel_path="NPI/probing/conditionals/scope_with_licensor") -@register_task("npi-cond-pr", rel_path="NPI/probing/conditionals/npi_present") -@register_task("npi-negdet-li", rel_path="NPI/probing/determiner_negation_biclausal/licensor") -@register_task( - "npi-negdet-sc", rel_path="NPI/probing/determiner_negation_biclausal/scope_with_licensor" -) -@register_task("npi-negdet-pr", rel_path="NPI/probing/determiner_negation_biclausal/npi_present") -@register_task("npi-negsent-li", rel_path="NPI/probing/sentential_negation_biclausal/licensor") -@register_task( - "npi-negsent-sc", rel_path="NPI/probing/sentential_negation_biclausal/scope_with_licensor" -) -@register_task("npi-negsent-pr", rel_path="NPI/probing/sentential_negation_biclausal/npi_present") -@register_task("npi-only-li", rel_path="NPI/probing/only/licensor") -@register_task("npi-only-sc", rel_path="NPI/probing/only/scope_with_licensor") -@register_task("npi-only-pr", rel_path="NPI/probing/only/npi_present") -@register_task("npi-qnt-li", rel_path="NPI/probing/quantifiers/licensor") -@register_task("npi-qnt-sc", rel_path="NPI/probing/quantifiers/scope_with_licensor") -@register_task("npi-qnt-pr", rel_path="NPI/probing/quantifiers/npi_present") -@register_task("npi-ques-li", rel_path="NPI/probing/questions/licensor") -@register_task("npi-ques-sc", rel_path="NPI/probing/questions/scope_with_licensor") -@register_task("npi-ques-pr", rel_path="NPI/probing/questions/npi_present") -@register_task("npi-quessmp-li", rel_path="NPI/probing/simplequestions/licensor") -@register_task("npi-quessmp-sc", rel_path="NPI/probing/simplequestions/scope_with_licensor") -@register_task("npi-quessmp-pr", rel_path="NPI/probing/simplequestions/npi_present") -@register_task("npi-sup-li", rel_path="NPI/probing/superlative/licensor") -@register_task("npi-sup-sc", rel_path="NPI/probing/superlative/scope_with_licensor") -@register_task("npi-sup-pr", rel_path="NPI/probing/superlative/npi_present") -@register_task("cola-npi-adv", rel_path="NPI/splits/adverbs") -@register_task("cola-npi-cond", rel_path="NPI/splits/conditionals") -@register_task("cola-npi-negdet", rel_path="NPI/splits/determiner_negation_biclausal") -@register_task("cola-npi-negsent", rel_path="NPI/splits/sentential_negation_biclausal") -@register_task("cola-npi-only", rel_path="NPI/splits/only") -@register_task("cola-npi-ques", rel_path="NPI/splits/questions") -@register_task("cola-npi-quessmp", rel_path="NPI/splits/simplequestions") -@register_task("cola-npi-qnt", rel_path="NPI/splits/quantifiers") -@register_task("cola-npi-sup", rel_path="NPI/splits/superlative") -@register_task("all-cola-npi", rel_path="NPI/combs/all_env") -@register_task("wilcox-npi", rel_path="NPI/wilcox") -@register_task("hd-cola-npi-adv", rel_path="NPI/combs/minus_adverbs") -@register_task("hd-cola-npi-cond", rel_path="NPI/combs/minus_conditionals") -@register_task("hd-cola-npi-negdet", rel_path="NPI/combs/minus_determiner_negation_biclausal") -@register_task("hd-cola-npi-negsent", rel_path="NPI/combs/minus_sentential_negation_biclausal") -@register_task("hd-cola-npi-only", rel_path="NPI/combs/minus_only") -@register_task("hd-cola-npi-ques", rel_path="NPI/combs/minus_questions") -@register_task("hd-cola-npi-quessmp", rel_path="NPI/combs/minus_simplequestions") -@register_task("hd-cola-npi-qnt", rel_path="NPI/combs/minus_quantifiers") -@register_task("hd-cola-npi-sup", rel_path="NPI/combs/minus_superlative") -class CoLANPITask(SingleClassificationTask): - """Class for NPI-related task; same with Warstdadt acceptability task but outputs labels for - test-set - Note: Used for an NYU seminar, data not yet public""" - - def __init__(self, path, max_seq_len, name, **kw): - super(CoLANPITask, self).__init__(name, n_classes=2, **kw) - self.path = path - self.max_seq_len = max_seq_len - - self.train_data_text = None - self.val_data_text = None - self.test_data_text = None - - self.val_metric = "%s_mcc" % self.name - self.val_metric_decreases = False - # self.scorer1 = Average() - self.scorer1 = Correlation("matthews") - self.scorer2 = CategoricalAccuracy() - self.scorers = [self.scorer1, self.scorer2] - - def load_data(self): - """Load the data""" - self.train_data_text = load_tsv( - self._tokenizer_name, - os.path.join(self.path, "train.tsv"), - max_seq_len=self.max_seq_len, - s1_idx=3, - s2_idx=None, - label_idx=1, - ) - self.val_data_text = load_tsv( - self._tokenizer_name, - os.path.join(self.path, "dev.tsv"), - max_seq_len=self.max_seq_len, - s1_idx=3, - s2_idx=None, - label_idx=1, - ) - self.test_data_text = load_tsv( - self._tokenizer_name, - os.path.join(self.path, "test_full.tsv"), - max_seq_len=self.max_seq_len, - s1_idx=3, - s2_idx=None, - label_idx=1, - ) - self.sentences = self.train_data_text[0] + self.val_data_text[0] - log.info("\tFinished loading NPI Data.") - - def get_metrics(self, reset=False): - return {"mcc": self.scorer1.get_metric(reset), "accuracy": self.scorer2.get_metric(reset)} - - def update_metrics(self, out, batch): - logits = out["logits"] - labels = out["labels"] - logits, labels = logits.detach(), labels.detach() - _, preds = logits.max(dim=1) - self.scorer1(preds, labels) - self.scorer2(logits, labels) - return - - -@register_task("cola", rel_path="CoLA/") -class CoLATask(SingleClassificationTask): - """Class for Warstdadt acceptability task""" - - def __init__(self, path, max_seq_len, name, **kw): - super(CoLATask, self).__init__(name, n_classes=2, **kw) - self.path = path - self.max_seq_len = max_seq_len - - self.train_data_text = None - self.val_data_text = None - self.test_data_text = None - - self.val_metric = "%s_mcc" % self.name - self.val_metric_decreases = False - # self.scorer1 = Average() - self.scorer1 = Correlation("matthews") - self.scorer2 = CategoricalAccuracy() - self.scorers = [self.scorer1, self.scorer2] - - def load_data(self): - """Load the data""" - self.train_data_text = load_tsv( - self._tokenizer_name, - os.path.join(self.path, "train.tsv"), - max_seq_len=self.max_seq_len, - s1_idx=3, - s2_idx=None, - label_idx=1, - ) - self.val_data_text = load_tsv( - self._tokenizer_name, - os.path.join(self.path, "dev.tsv"), - max_seq_len=self.max_seq_len, - s1_idx=3, - s2_idx=None, - label_idx=1, - ) - self.test_data_text = load_tsv( - self._tokenizer_name, - os.path.join(self.path, "test.tsv"), - max_seq_len=self.max_seq_len, - s1_idx=1, - s2_idx=None, - has_labels=False, - return_indices=True, - skip_rows=1, - ) - self.sentences = self.train_data_text[0] + self.val_data_text[0] - log.info("\tFinished loading CoLA.") - - def get_metrics(self, reset=False): - return {"mcc": self.scorer1.get_metric(reset), "accuracy": self.scorer2.get_metric(reset)} - - def update_metrics(self, out, batch): - logits = out["logits"] - labels = out["labels"] - logits, labels = logits.detach(), labels.detach() - _, preds = logits.max(dim=1) - self.scorer1(preds, labels) - self.scorer2(logits, labels) - return - - -@register_task("cola-analysis", rel_path="CoLA/") -class CoLAAnalysisTask(SingleClassificationTask): - def __init__(self, path, max_seq_len, name, **kw): - super(CoLAAnalysisTask, self).__init__(name, n_classes=2, **kw) - self.path = path - self.max_seq_len = max_seq_len - - self.train_data_text = None - self.val_data_text = None - self.test_data_text = None - - self.tag_list = None - self.tag_scorers1 = None - self.tag_scorers2 = None - - self.val_metric = "%s_mcc" % self.name - self.val_metric_decreases = False - self.scorer1 = Correlation("matthews") - self.scorer2 = CategoricalAccuracy() - self.scorers = [self.scorer1, self.scorer2] - - def load_data(self): - """Load the data""" - # Load data from tsv - tag_vocab = vocabulary.Vocabulary(counter=None) - tr_data = load_tsv( - tokenizer_name=self._tokenizer_name, - data_file=os.path.join(self.path, "train_analysis.tsv"), - max_seq_len=self.max_seq_len, - s1_idx=3, - s2_idx=None, - label_idx=2, - skip_rows=1, - tag2idx_dict={"Domain": 1}, - tag_vocab=tag_vocab, - ) - val_data = load_tsv( - tokenizer_name=self._tokenizer_name, - data_file=os.path.join(self.path, "dev_analysis.tsv"), - max_seq_len=self.max_seq_len, - s1_idx=3, - s2_idx=None, - label_idx=2, - skip_rows=1, - tag2idx_dict={ - "Domain": 1, - "Simple": 4, - "Pred": 5, - "Adjunct": 6, - "Arg Types": 7, - "Arg Altern": 8, - "Imperative": 9, - "Binding": 10, - "Question": 11, - "Comp Clause": 12, - "Auxillary": 13, - "to-VP": 14, - "N, Adj": 15, - "S-Syntax": 16, - "Determiner": 17, - "Violations": 18, - }, - tag_vocab=tag_vocab, - ) - te_data = load_tsv( - tokenizer_name=self._tokenizer_name, - data_file=os.path.join(self.path, "test_analysis.tsv"), - max_seq_len=self.max_seq_len, - s1_idx=3, - s2_idx=None, - label_idx=2, - skip_rows=1, - tag2idx_dict={"Domain": 1}, - tag_vocab=tag_vocab, - ) - self.train_data_text = tr_data[:1] + tr_data[2:] - self.val_data_text = val_data[:1] + val_data[2:] - self.test_data_text = te_data[:1] + te_data[2:] - self.sentences = self.train_data_text[0] + self.val_data_text[0] - # Create score for each tag from tag-index dict - self.tag_list = get_tag_list(tag_vocab) - self.tag_scorers1 = create_subset_scorers( - count=len(self.tag_list), scorer_type=Correlation, corr_type="matthews" - ) - self.tag_scorers2 = create_subset_scorers( - count=len(self.tag_list), scorer_type=CategoricalAccuracy - ) - log.info("\tFinished loading CoLA sperate domain.") - - def process_split(self, split, indexers, model_preprocessing_interface): - def _make_instance(input1, labels, tagids): - """ from multiple types in one column create multiple fields """ - d = {} - d["input1"] = sentence_to_text_field( - model_preprocessing_interface.boundary_token_fn(input1), indexers - ) - d["sent1_str"] = MetadataField(" ".join(input1)) - d["labels"] = LabelField(labels, label_namespace="labels", skip_indexing=True) - d["tagmask"] = MultiLabelField( - tagids, label_namespace="tags", skip_indexing=True, num_labels=len(self.tag_list) - ) - return Instance(d) - - instances = map(_make_instance, *split) - return instances # lazy iterator - - def update_metrics(self, out, batch): - logits = out["logits"] - labels = out["labels"] - tagmask = batch.get("tagmask", None) - logits, labels = logits.detach(), labels.detach() - _, preds = logits.max(dim=1) - self.scorer1(preds, labels) - self.scorer2(logits, labels) - if tagmask is not None: - update_subset_scorers(self.tag_scorers1, preds, labels, tagmask) - update_subset_scorers(self.tag_scorers2, logits, labels, tagmask) - return - - def get_metrics(self, reset=False): - """Get metrics specific to the task""" - - collected_metrics = { - "mcc": self.scorer1.get_metric(reset), - "accuracy": self.scorer2.get_metric(reset), - } - collected_metrics.update( - collect_subset_scores(self.tag_scorers1, "mcc", self.tag_list, reset) - ) - collected_metrics.update( - collect_subset_scores(self.tag_scorers2, "accuracy", self.tag_list, reset) - ) - return collected_metrics - - -@register_task("qqp", rel_path="QQP/") -@register_task("qqp-alt", rel_path="QQP/") # second copy for different params -class QQPTask(PairClassificationTask): - """ Task class for Quora Question Pairs. """ - - def __init__(self, path, max_seq_len, name, **kw): - super().__init__(name, n_classes=2, **kw) - self.path = path - self.max_seq_len = max_seq_len - - self.train_data_text = None - self.val_data_text = None - self.test_data_text = None - - self.scorer2 = F1Measure(1) - self.scorers = [self.scorer1, self.scorer2] - self.val_metric = "%s_acc_f1" % name - self.val_metric_decreases = False - - def load_data(self): - """Process the dataset located at data_file.""" - - def label_fn(x): - if x == "": - return 0 - else: - return int(x) - - self.train_data_text = load_tsv( - self._tokenizer_name, - os.path.join(self.path, "train.tsv"), - max_seq_len=self.max_seq_len, - s1_idx=3, - s2_idx=4, - label_idx=5, - label_fn=label_fn, - skip_rows=1, - ) - self.val_data_text = load_tsv( - self._tokenizer_name, - os.path.join(self.path, "dev.tsv"), - max_seq_len=self.max_seq_len, - s1_idx=3, - s2_idx=4, - label_idx=5, - label_fn=label_fn, - skip_rows=1, - ) - self.test_data_text = load_tsv( - self._tokenizer_name, - os.path.join(self.path, "test.tsv"), - max_seq_len=self.max_seq_len, - s1_idx=1, - s2_idx=2, - has_labels=False, - return_indices=True, - skip_rows=1, - ) - self.sentences = ( - self.train_data_text[0] - + self.train_data_text[1] - + self.val_data_text[0] - + self.val_data_text[1] - ) - log.info("\tFinished loading QQP data.") - - def get_metrics(self, reset=False): - """Get metrics specific to the task""" - acc = self.scorer1.get_metric(reset) - pcs, rcl, f1 = self.scorer2.get_metric(reset) - return { - "acc_f1": (acc + f1) / 2, - "accuracy": acc, - "f1": f1, - "precision": pcs, - "recall": rcl, - } - - def process_split( - self, split, indexers, model_preprocessing_interface - ) -> Iterable[Type[Instance]]: - """ Process split text into a list of AllenNLP Instances. """ - return process_single_pair_task_split( - split, indexers, model_preprocessing_interface, is_pair=True, is_symmetrical_pair=True - ) - - -@register_task("mrpc", rel_path="MRPC/") -class MRPCTask(PairClassificationTask): - """Task class for Microsoft Research Paraphase Task.""" - - def __init__(self, path, max_seq_len, name, **kw): - super(MRPCTask, self).__init__(name, n_classes=2, **kw) - self.path = path - self.max_seq_len = max_seq_len - - self.train_data_text = None - self.val_data_text = None - self.test_data_text = None - - self.scorer2 = F1Measure(1) - self.scorers = [self.scorer1, self.scorer2] - self.val_metric = "%s_acc_f1" % name - self.val_metric_decreases = False - - def load_data(self): - """ Process the dataset located at path. """ - self.train_data_text = load_tsv( - self._tokenizer_name, - os.path.join(self.path, "train.tsv"), - max_seq_len=self.max_seq_len, - s1_idx=3, - s2_idx=4, - label_idx=0, - skip_rows=1, - ) - self.val_data_text = load_tsv( - self._tokenizer_name, - os.path.join(self.path, "dev.tsv"), - max_seq_len=self.max_seq_len, - s1_idx=3, - s2_idx=4, - label_idx=0, - skip_rows=1, - ) - self.test_data_text = load_tsv( - self._tokenizer_name, - os.path.join(self.path, "test.tsv"), - max_seq_len=self.max_seq_len, - s1_idx=3, - s2_idx=4, - has_labels=False, - return_indices=True, - skip_rows=1, - ) - self.sentences = ( - self.train_data_text[0] - + self.train_data_text[1] - + self.val_data_text[0] - + self.val_data_text[1] - ) - log.info("\tFinished loading MRPC data.") - - def get_metrics(self, reset=False): - """Get metrics specific to the task""" - acc = self.scorer1.get_metric(reset) - pcs, rcl, f1 = self.scorer2.get_metric(reset) - return { - "acc_f1": (acc + f1) / 2, - "accuracy": acc, - "f1": f1, - "precision": pcs, - "recall": rcl, - } - - def process_split( - self, split, indexers, model_preprocessing_interface - ) -> Iterable[Type[Instance]]: - """ Process split text into a list of AllenNLP Instances. """ - return process_single_pair_task_split( - split, indexers, model_preprocessing_interface, is_pair=True, is_symmetrical_pair=True - ) - - -@register_task("sts-b", rel_path="STS-B/") -# second copy for different params -@register_task("sts-b-alt", rel_path="STS-B/") -class STSBTask(PairRegressionTask): - """ Task class for Sentence Textual Similarity Benchmark. """ - - def __init__(self, path, max_seq_len, name, **kw): - super(STSBTask, self).__init__(name, **kw) - self.path = path - self.max_seq_len = max_seq_len - - self.train_data_text = None - self.val_data_text = None - self.test_data_text = None - - self.scorer1 = Correlation("pearson") - self.scorer2 = Correlation("spearman") - self.scorers = [self.scorer1, self.scorer2] - self.val_metric = "%s_corr" % self.name - self.val_metric_decreases = False - - def load_data(self): - """ Load data """ - self.train_data_text = load_tsv( - self._tokenizer_name, - os.path.join(self.path, "train.tsv"), - max_seq_len=self.max_seq_len, - skip_rows=1, - s1_idx=7, - s2_idx=8, - label_idx=9, - label_fn=lambda x: float(x) / 5, - ) - self.val_data_text = load_tsv( - self._tokenizer_name, - os.path.join(self.path, "dev.tsv"), - max_seq_len=self.max_seq_len, - skip_rows=1, - s1_idx=7, - s2_idx=8, - label_idx=9, - label_fn=lambda x: float(x) / 5, - ) - self.test_data_text = load_tsv( - self._tokenizer_name, - os.path.join(self.path, "test.tsv"), - max_seq_len=self.max_seq_len, - s1_idx=7, - s2_idx=8, - has_labels=False, - return_indices=True, - skip_rows=1, - ) - self.sentences = ( - self.train_data_text[0] - + self.train_data_text[1] - + self.val_data_text[0] - + self.val_data_text[1] - ) - log.info("\tFinished loading STS Benchmark data.") - - def get_metrics(self, reset=False): - pearsonr = self.scorer1.get_metric(reset) - spearmanr = self.scorer2.get_metric(reset) - return {"corr": (pearsonr + spearmanr) / 2, "pearsonr": pearsonr, "spearmanr": spearmanr} - - def process_split( - self, split, indexers, model_preprocessing_interface - ) -> Iterable[Type[Instance]]: - """ Process split text into a list of AllenNLP Instances. """ - return process_single_pair_task_split( - split, - indexers, - model_preprocessing_interface, - is_pair=True, - classification=False, - is_symmetrical_pair=True, - ) - - -@register_task("snli", rel_path="SNLI/") -class SNLITask(PairClassificationTask): - """ Task class for Stanford Natural Language Inference """ - - def __init__(self, path, max_seq_len, name, **kw): - """ Do stuff """ - super(SNLITask, self).__init__(name, n_classes=3, **kw) - self.path = path - self.max_seq_len = max_seq_len - - self.train_data_text = None - self.val_data_text = None - self.test_data_text = None - - def load_data(self): - """ Process the dataset located at path. """ - targ_map = {"neutral": 0, "entailment": 1, "contradiction": 2} - - def _load_jsonl(data_file): - data = [json.loads(d) for d in open(data_file, encoding="utf-8")] - sent1s, sent2s, trgs, idxs = [], [], [], [] - for idx, example in enumerate(data): - if example["gold_label"] not in targ_map: - # some examples don't have annotator agreement so no gold label - continue - - sent1s.append( - tokenize_and_truncate( - self._tokenizer_name, example["sentence1"], self.max_seq_len - ) - ) - sent2s.append( - tokenize_and_truncate( - self._tokenizer_name, example["sentence2"], self.max_seq_len - ) - ) - trg = targ_map[example["gold_label"]] - trgs.append(trg) - idxs.append(idx) - return [sent1s, sent2s, trgs, idxs] - - self.train_data_text = _load_jsonl(os.path.join(self.path, "train.jsonl")) - self.val_data_text = _load_jsonl(os.path.join(self.path, "dev.jsonl")) - self.test_data_text = _load_jsonl(os.path.join(self.path, "test.jsonl")) - - self.sentences = ( - self.train_data_text[0] - + self.train_data_text[1] - + self.val_data_text[0] - + self.val_data_text[1] - ) - log.info("\tFinished loading SNLI data.") - - -@register_task("adversarial-nli-a1", rel_path="AdversarialNLI/", datasets=["R1"]) -@register_task("adversarial-nli-a2", rel_path="AdversarialNLI/", datasets=["R2"]) -@register_task("adversarial-nli-a3", rel_path="AdversarialNLI/", datasets=["R3"]) -@register_task("adversarial-nli", rel_path="AdversarialNLI/", datasets=["R1", "R2", "R3"]) -class AdversarialNLITask(PairClassificationTask): - """Task class for use with Adversarial Natural Language Inference dataset. - - Configures a 3-class PairClassificationTask using Adversarial NLI data. - Requires original ANLI dataset file structure under the relative path. - Data: https://dl.fbaipublicfiles.com/anli/anli_v0.1.zip - Paper: https://arxiv.org/abs/1910.14599 - - Attributes: - path (str): AdversarialNLI path relative to JIANT_DATA_DIR - max_seq_len (int): max tokens allowed in a sequence - train_data_text (list[list[str], list[str], list[int]]): - list of lists of context, hypothesis, and target training data - val_data_text (list[list[str], list[str], list[int]]): - list of lists of context, hypothesis, and target val data - test_data_text (list[list[str], list[str], list[int]]): - list of lists of context, hypothesis, and target test data - datasets (list[str]): list of sub-datasets used in task (e.g., R1) - sentences (list): list of all (tokenized) context and hypothesis - texts from train and val data. - """ - - def __init__(self, path, max_seq_len, name, datasets, **kw): - """Initialize an AdversarialNLITask task. - - Args: - path (str): AdversarialNLI path relative to the data dir - max_seq_len (int): max tokens allowed in a sequence - name (str): task name, specified in @register_task - datasets (list[str]): list of ANLI sub-datasets used in task - """ - super(AdversarialNLITask, self).__init__(name, n_classes=3, **kw) - self.path = path - self.max_seq_len = max_seq_len - self.train_data_text = None - self.val_data_text = None - self.test_data_text = None - self.datasets = datasets - - def _read_data(self, path: str) -> pd.core.frame.DataFrame: - """Read json, tokenize text, encode labels as int, return dataframe.""" - df = pd.read_json(path_or_buf=path, encoding="UTF-8", lines=True) - # for ANLI datasets n=neutral, e=entailment, c=contradiction - df["target"] = df["label"].map({"n": 0, "e": 1, "c": 2}) - tokenizer = get_tokenizer(self._tokenizer_name) - df["context"] = df["context"].apply(tokenizer.tokenize) - df["hypothesis"] = df["hypothesis"].apply(tokenizer.tokenize) - return df[["context", "hypothesis", "target"]] - - def load_data(self): - """Read, preprocess and load data into an AdversarialNLITask. - - Assumes original dataset file structure under `self.rel_path`. - Loads only the datasets (e.g., "R1") specified in the `datasets` attr. - Populates task train_, val_, test_data_text and `sentence` attr. - """ - train_dfs, val_dfs, test_dfs = [], [], [] - for dataset in self.datasets: - train_dfs.append(self._read_data(os.path.join(self.path, dataset, "train.jsonl"))) - val_dfs.append(self._read_data(os.path.join(self.path, dataset, "dev.jsonl"))) - test_dfs.append(self._read_data(os.path.join(self.path, dataset, "test.jsonl"))) - train_df = pd.concat(train_dfs, axis=0, ignore_index=True) - val_df = pd.concat(val_dfs, axis=0, ignore_index=True) - test_df = pd.concat(test_dfs, axis=0, ignore_index=True) - - self.train_data_text = [ - train_df["context"].tolist(), - train_df["hypothesis"].tolist(), - train_df["target"].tolist(), - ] - self.val_data_text = [ - val_df["context"].tolist(), - val_df["hypothesis"].tolist(), - val_df["target"].tolist(), - ] - self.test_data_text = [ - test_df["context"].tolist(), - test_df["hypothesis"].tolist(), - test_df["target"].tolist(), - ] - - self.sentences = ( - train_df["context"].tolist() - + train_df["hypothesis"].tolist() - + val_df["context"].tolist() - + val_df["hypothesis"].tolist() - ) - - log.info("\tFinished loading ANLI data: " + self.name) - - -@register_task("mnli", rel_path="MNLI/") -# Alternate version with a modified evaluation metric. For use in transfer evaluations on -# two-class test sets like RTE. Example config override: -# pretrain_tasks = mnli, target_tasks = \"mnli-two,rte\", rte += {use_classifier = mnli-two} -@register_task("mnli-two", rel_path="MNLI/", two_class_evaluation=True) -# Second copy that can be assigned separate task-specific config options. -@register_task("mnli-alt", rel_path="MNLI/") -@register_task("mnli-fiction", rel_path="MNLI/", genre="fiction") -@register_task("mnli-slate", rel_path="MNLI/", genre="slate") -@register_task("mnli-government", rel_path="MNLI/", genre="government") -@register_task("mnli-telephone", rel_path="MNLI/", genre="telephone") -@register_task("mnli-travel", rel_path="MNLI/", genre="travel") -class MultiNLITask(PairClassificationTask): - """ Task class for Multi-Genre Natural Language Inference. """ - - def __init__(self, path, max_seq_len, name, genre=None, two_class_evaluation=False, **kw): - """Set up the MNLI task object. - - When genre is set to one of the ten MNLI genres, only examples matching that genre will be - loaded in any split. That may result in some of the sections (train, dev mismatched, ...) - being empty. - - When two_class_evaluation is set, merge the contradiction and neutral labels, for both - predictions and gold labels, in the metric when evaluating on this task. - """ - super(MultiNLITask, self).__init__(name, n_classes=3, **kw) - self.path = path - self.max_seq_len = max_seq_len - self.genre = genre - if two_class_evaluation: - self.scorer1 = NLITwoClassAccuracy() - self.scorers = [self.scorer1] - - self.train_data_text = None - self.val_data_text = None - self.test_data_text = None - - def load_data(self): - """Process the dataset located at path.""" - targ_map = {"neutral": 0, "entailment": 1, "contradiction": 2} - tr_data = load_tsv( - self._tokenizer_name, - os.path.join(self.path, "train.tsv"), - max_seq_len=self.max_seq_len, - s1_idx=8, - s2_idx=9, - label_idx=11, - label_fn=targ_map.__getitem__, - skip_rows=1, - filter_idx=3, - filter_value=self.genre, - ) - - # Warning to anyone who edits this: The reference label is column *15*, - # not 11 as above. - val_matched_data = load_tsv( - self._tokenizer_name, - os.path.join(self.path, "dev_matched.tsv"), - max_seq_len=self.max_seq_len, - s1_idx=8, - s2_idx=9, - label_idx=15, - label_fn=targ_map.__getitem__, - skip_rows=1, - filter_idx=3, - filter_value=self.genre, - ) - val_mismatched_data = load_tsv( - self._tokenizer_name, - os.path.join(self.path, "dev_mismatched.tsv"), - max_seq_len=self.max_seq_len, - s1_idx=8, - s2_idx=9, - label_idx=15, - label_fn=targ_map.__getitem__, - skip_rows=1, - filter_idx=3, - filter_value=self.genre, - ) - val_data = [m + mm for m, mm in zip(val_matched_data, val_mismatched_data)] - val_data = tuple(val_data) - - te_matched_data = load_tsv( - self._tokenizer_name, - os.path.join(self.path, "test_matched.tsv"), - max_seq_len=self.max_seq_len, - s1_idx=8, - s2_idx=9, - has_labels=False, - return_indices=True, - skip_rows=1, - filter_idx=3, - filter_value=self.genre, - ) - te_mismatched_data = load_tsv( - self._tokenizer_name, - os.path.join(self.path, "test_mismatched.tsv"), - max_seq_len=self.max_seq_len, - s1_idx=8, - s2_idx=9, - has_labels=False, - return_indices=True, - skip_rows=1, - filter_idx=3, - filter_value=self.genre, - ) - te_data = [m + mm for m, mm in zip(te_matched_data, te_mismatched_data)] - - self.train_data_text = tr_data - self.val_data_text = val_data - self.test_data_text = te_data - self.sentences = ( - self.train_data_text[0] - + self.train_data_text[1] - + self.val_data_text[0] - + self.val_data_text[1] - ) - log.info("\tFinished loading MNLI data.") - - -@register_task("mnli-ho", rel_path="MNLI/") -@register_task("mnli-two-ho", rel_path="MNLI/", two_class_evaluation=True) -@register_task("mnli-fiction-ho", rel_path="MNLI/", genre="fiction") -@register_task("mnli-slate-ho", rel_path="MNLI/", genre="slate") -@register_task("mnli-government-ho", rel_path="MNLI/", genre="government") -@register_task("mnli-telephone-ho", rel_path="MNLI/", genre="telephone") -@register_task("mnli-travel-ho", rel_path="MNLI/", genre="travel") -class MultiNLIHypothesisOnlyTask(SingleClassificationTask): - """ Task class for MultiNLI hypothesis-only classification. """ - - def __init__(self, path, max_seq_len, name, genre=None, two_class_evaluation=False, **kw): - """Set up the MNLI-HO task object. - - When genre is set to one of the ten MNLI genres, only examples matching that genre will be - loaded in any split. That may result in some of the sections (train, dev mismatched, ...) - being empty. - - When two_class_evaluation is set, merge the contradiction and neutral labels, for both - predictions and gold labels, in the metric when evaluating on this task. - """ - super(MultiNLIHypothesisOnlyTask, self).__init__(name, n_classes=3, **kw) - self.path = path - self.max_seq_len = max_seq_len - self.genre = genre - - if two_class_evaluation: - self.scorer1 = NLITwoClassAccuracy() - self.scorers = [self.scorer1] - - self.train_data_text = None - self.val_data_text = None - self.test_data_text = None - - def load_data(self): - """Process the dataset located at path.""" - targ_map = {"neutral": 0, "entailment": 1, "contradiction": 2} - tr_data = load_tsv( - self._tokenizer_name, - os.path.join(self.path, "train.tsv"), - max_seq_len=self.max_seq_len, - s1_idx=9, - s2_idx=None, - label_idx=11, - label_fn=targ_map.__getitem__, - skip_rows=1, - filter_idx=3, - filter_value=self.genre, - ) - - # Warning to anyone who edits this: The reference label is column *15*, - # not 11 as above. - val_matched_data = load_tsv( - self._tokenizer_name, - os.path.join(self.path, "dev_matched.tsv"), - max_seq_len=self.max_seq_len, - s1_idx=9, - s2_idx=None, - label_idx=15, - label_fn=targ_map.__getitem__, - skip_rows=1, - filter_idx=3, - filter_value=self.genre, - ) - val_mismatched_data = load_tsv( - self._tokenizer_name, - os.path.join(self.path, "dev_mismatched.tsv"), - max_seq_len=self.max_seq_len, - s1_idx=9, - s2_idx=None, - label_idx=15, - label_fn=targ_map.__getitem__, - skip_rows=1, - filter_idx=3, - filter_value=self.genre, - ) - val_data = [m + mm for m, mm in zip(val_matched_data, val_mismatched_data)] - val_data = tuple(val_data) - - te_matched_data = load_tsv( - self._tokenizer_name, - os.path.join(self.path, "test_matched.tsv"), - max_seq_len=self.max_seq_len, - s1_idx=9, - s2_idx=None, - has_labels=False, - return_indices=True, - skip_rows=1, - filter_idx=3, - filter_value=self.genre, - ) - te_mismatched_data = load_tsv( - self._tokenizer_name, - os.path.join(self.path, "test_mismatched.tsv"), - max_seq_len=self.max_seq_len, - s1_idx=9, - s2_idx=None, - has_labels=False, - return_indices=True, - skip_rows=1, - filter_idx=3, - filter_value=self.genre, - ) - te_data = [m + mm for m, mm in zip(te_matched_data, te_mismatched_data)] - - self.train_data_text = tr_data - self.val_data_text = val_data - self.test_data_text = te_data - self.sentences = self.train_data_text[0] + self.val_data_text[0] - log.info("\tFinished loading MNLI-HO data.") - - -# GLUE diagnostic (3-class NLI), expects TSV -@register_task("glue-diagnostic", rel_path="MNLI/", n_classes=3) -# GLUE diagnostic (2 class NLI, merging neutral and contradiction into not_entailment) -@register_task("glue-diagnostic-binary", rel_path="RTE/", n_classes=2) -class GLUEDiagnosticTask(PairClassificationTask): - """ Task class for GLUE diagnostic data """ - - def __init__(self, path, max_seq_len, name, n_classes, **kw): - super().__init__(name, n_classes, **kw) - self.path = path - self.max_seq_len = max_seq_len - self.n_classes = n_classes - - self.train_data_text = None - self.val_data_text = None - self.test_data_text = None - - self.ix_to_lex_sem_dic = None - self.ix_to_pr_ar_str_dic = None - self.ix_to_logic_dic = None - self.ix_to_knowledge_dic = None - self._scorer_all_mcc = None - self._scorer_all_acc = None - - self.contributes_to_aggregate_score = False - self.eval_only_task = True - - def load_data(self): - """load diagnostics data. The tags for every column are loaded as indices. - They will be converted to bools in preprocess_split function""" - - # Will create separate scorer for every tag. tag_group is the name of the - # column it will have its own scorer - def create_score_function(scorer, arg_to_scorer, tags_dict, tag_group): - setattr(self, "scorer__%s" % tag_group, scorer(arg_to_scorer)) - for index, tag in tags_dict.items(): - # 0 is missing value - if index == 0: - continue - setattr(self, "scorer__%s__%s" % (tag_group, tag), scorer(arg_to_scorer)) - - if self.n_classes == 2: - targ_map = {"neutral": 0, "entailment": 1, "contradiction": 0} - elif self.n_classes == 3: - targ_map = {"neutral": 0, "entailment": 1, "contradiction": 2} - else: - raise ValueError("Invalid number of classes for NLI task") - - diag_data_dic = load_diagnostic_tsv( - self._tokenizer_name, - os.path.join(self.path, "diagnostic-full.tsv"), - max_seq_len=self.max_seq_len, - s1_col="Premise", - s2_col="Hypothesis", - label_col="Label", - label_fn=targ_map.__getitem__, - skip_rows=1, - ) - - self.ix_to_lex_sem_dic = diag_data_dic["ix_to_lex_sem_dic"] - self.ix_to_pr_ar_str_dic = diag_data_dic["ix_to_pr_ar_str_dic"] - self.ix_to_logic_dic = diag_data_dic["ix_to_logic_dic"] - self.ix_to_knowledge_dic = diag_data_dic["ix_to_knowledge_dic"] - - # Train, val, test splits are same. We only need one split but the code - # probably expects all splits to be present. - self.train_data_text = ( - diag_data_dic["sents1"], - diag_data_dic["sents2"], - diag_data_dic["targs"], - diag_data_dic["idxs"], - diag_data_dic["lex_sem"], - diag_data_dic["pr_ar_str"], - diag_data_dic["logic"], - diag_data_dic["knowledge"], - ) - self.val_data_text = self.train_data_text - self.test_data_text = self.train_data_text - self.sentences = ( - self.train_data_text[0] - + self.train_data_text[1] - + self.val_data_text[0] - + self.val_data_text[1] - ) - log.info("\tFinished loading diagnostic data.") - - # TODO: use FastMatthews instead to save memory. - create_score_function(Correlation, "matthews", self.ix_to_lex_sem_dic, "lex_sem") - create_score_function(Correlation, "matthews", self.ix_to_pr_ar_str_dic, "pr_ar_str") - create_score_function(Correlation, "matthews", self.ix_to_logic_dic, "logic") - create_score_function(Correlation, "matthews", self.ix_to_knowledge_dic, "knowledge") - self._scorer_all_mcc = Correlation("matthews") # score all examples according to MCC - self._scorer_all_acc = CategoricalAccuracy() # score all examples according to acc - log.info("\tFinished creating score functions for diagnostic data.") - - def update_metrics(self, out, batch): - self.update_diagnostic_metrics(out["logits"], batch["labels"], batch) - - def update_diagnostic_metrics(self, logits, labels, batch): - # Updates scorer for every tag in a given column (tag_group) and also the - # the scorer for the column itself. - _, preds = logits.max(dim=1) - - def update_scores_for_tag_group(ix_to_tags_dic, tag_group): - for ix, tag in ix_to_tags_dic.items(): - # 0 is for missing tag so here we use it to update scorer for the column - # itself (tag_group). - if ix == 0: - # This will contain 1s on positions where at least one of the tags of this - # column is present. - mask = batch[tag_group] - scorer_str = "scorer__%s" % tag_group - # This branch will update scorers of individual tags in the - # column - else: - # batch contains_field for every tag. It's either 0 or 1. - mask = batch["%s__%s" % (tag_group, tag)] - scorer_str = "scorer__%s__%s" % (tag_group, tag) - - # This will take only values for which the tag is true. - indices_to_pull = torch.nonzero(mask) - # No example in the batch is labeled with the tag. - if indices_to_pull.size()[0] == 0: - continue - sub_labels = labels[indices_to_pull[:, 0]] - sub_preds = preds[indices_to_pull[:, 0]] - scorer = getattr(self, scorer_str) - scorer(sub_preds, sub_labels) - return - - # Updates scorers for each tag. - update_scores_for_tag_group(self.ix_to_lex_sem_dic, "lex_sem") - update_scores_for_tag_group(self.ix_to_pr_ar_str_dic, "pr_ar_str") - update_scores_for_tag_group(self.ix_to_logic_dic, "logic") - update_scores_for_tag_group(self.ix_to_knowledge_dic, "knowledge") - self._scorer_all_mcc(preds, labels) - self._scorer_all_acc(logits, labels) - - def process_split( - self, split, indexers, model_preprocessing_interface - ) -> Iterable[Type[Instance]]: - """ Process split text into a list of AllenNLP Instances. """ - - def create_labels_from_tags(fields_dict, ix_to_tag_dict, tag_arr, tag_group): - # If there is something in this row then tag_group should be set to - # 1. - is_tag_group = 1 if len(tag_arr) != 0 else 0 - fields_dict[tag_group] = LabelField( - is_tag_group, label_namespace=tag_group + "_tags", skip_indexing=True - ) - # For every possible tag in the column set 1 if the tag is present for - # this example, 0 otherwise. - for ix, tag in ix_to_tag_dict.items(): - if ix == 0: - continue - is_present = 1 if ix in tag_arr else 0 - fields_dict["%s__%s" % (tag_group, tag)] = LabelField( - is_present, label_namespace="%s__%s_tags" % (tag_group, tag), skip_indexing=True - ) - return - - def _make_instance(input1, input2, label, idx, lex_sem, pr_ar_str, logic, knowledge): - """ from multiple types in one column create multiple fields """ - d = {} - if model_preprocessing_interface.model_flags["uses_pair_embedding"]: - inp = model_preprocessing_interface.boundary_token_fn(input1, input2) - d["inputs"] = sentence_to_text_field(inp, indexers) - else: - d["input1"] = sentence_to_text_field( - model_preprocessing_interface.boundary_token_fn(input1), indexers - ) - d["input2"] = sentence_to_text_field( - model_preprocessing_interface.boundary_token_fn(input2), indexers - ) - d["labels"] = LabelField(label, label_namespace="labels", skip_indexing=True) - d["idx"] = LabelField(idx, label_namespace="idx_tags", skip_indexing=True) - d["sent1_str"] = MetadataField(" ".join(input1)) - d["sent2_str"] = MetadataField(" ".join(input2)) - - # adds keys to dict "d" for every possible type in the column - create_labels_from_tags(d, self.ix_to_lex_sem_dic, lex_sem, "lex_sem") - create_labels_from_tags(d, self.ix_to_pr_ar_str_dic, pr_ar_str, "pr_ar_str") - create_labels_from_tags(d, self.ix_to_logic_dic, logic, "logic") - create_labels_from_tags(d, self.ix_to_knowledge_dic, knowledge, "knowledge") - - return Instance(d) - - instances = map(_make_instance, *split) - # return list(instances) - return instances # lazy iterator - - def get_metrics(self, reset=False): - """Get metrics specific to the task""" - collected_metrics = {} - - def collect_metrics(ix_to_tag_dict, tag_group): - for index, tag in ix_to_tag_dict.items(): - # Index 0 is used for missing data, here it will be used for score of the - # whole category. - if index == 0: - scorer_str = "scorer__%s" % tag_group - scorer = getattr(self, scorer_str) - collected_metrics["%s" % (tag_group)] = scorer.get_metric(reset) - else: - scorer_str = "scorer__%s__%s" % (tag_group, tag) - scorer = getattr(self, scorer_str) - collected_metrics["%s__%s" % (tag_group, tag)] = scorer.get_metric(reset) - - collect_metrics(self.ix_to_lex_sem_dic, "lex_sem") - collect_metrics(self.ix_to_pr_ar_str_dic, "pr_ar_str") - collect_metrics(self.ix_to_logic_dic, "logic") - collect_metrics(self.ix_to_knowledge_dic, "knowledge") - collected_metrics["all_mcc"] = self._scorer_all_mcc.get_metric(reset) - collected_metrics["accuracy"] = self._scorer_all_acc.get_metric(reset) - return collected_metrics - - -# SuperGLUE diagnostic (2-class NLI), expects JSONL -@register_task("broadcoverage-diagnostic", rel_path="RTE/diagnostics") -class BroadCoverageDiagnosticTask(GLUEDiagnosticTask): - """ Class for SuperGLUE broad coverage (linguistics, commonsense, world knowledge) - diagnostic task """ - - def __init__(self, path, max_seq_len, name, **kw): - super().__init__(path, max_seq_len, name, n_classes=2, **kw) - self.path = path - self.max_seq_len = max_seq_len - self.n_classes = 2 - - self.train_data_text = None - self.val_data_text = None - self.test_data_text = None - - self.ix_to_lex_sem_dic = None - self.ix_to_pr_ar_str_dic = None - self.ix_to_logic_dic = None - self.ix_to_knowledge_dic = None - self._scorer_all_mcc = None - self._scorer_all_acc = None - self.eval_only_task = True - - def load_data(self): - """load diagnostics data. The tags for every column are loaded as indices. - They will be converted to bools in preprocess_split function""" - - def _build_label_vocab(labelspace, data): - """ This function builds the vocab mapping for a particular labelspace, - which in practice is a coarse-grained diagnostic category. """ - values = set([d[labelspace] for d in data if labelspace in d]) - vocab = vocabulary.Vocabulary(counter=None, non_padded_namespaces=[labelspace]) - for value in values: - vocab.add_token_to_namespace(value, labelspace) - idx_to_word = vocab.get_index_to_token_vocabulary(labelspace) - word_to_idx = vocab.get_token_to_index_vocabulary(labelspace) - indexed = [[word_to_idx[d[labelspace]]] if labelspace in d else [] for d in data] - return word_to_idx, idx_to_word, indexed - - def create_score_function(scorer, arg_to_scorer, tags_dict, tag_group): - """ Create a scorer for each tag in a given tag group. - The entire tag_group also has its own scorer""" - setattr(self, "scorer__%s" % tag_group, scorer(arg_to_scorer)) - for index, tag in tags_dict.items(): - # 0 is missing value - if index == 0: - continue - setattr(self, "scorer__%s__%s" % (tag_group, tag), scorer(arg_to_scorer)) - - targ_map = {"entailment": 1, "not_entailment": 0} - data = [json.loads(d) for d in open(os.path.join(self.path, "AX-b.jsonl"))] - sent1s = [ - tokenize_and_truncate(self._tokenizer_name, d["sentence1"], self.max_seq_len) - for d in data - ] - sent2s = [ - tokenize_and_truncate(self._tokenizer_name, d["sentence2"], self.max_seq_len) - for d in data - ] - labels = [targ_map[d["label"]] for d in data] - idxs = [int(d["idx"]) for d in data] - lxs2idx, idx2lxs, lxs = _build_label_vocab("lexical-semantics", data) - pas2idx, idx2pas, pas = _build_label_vocab("predicate-argument-structure", data) - lgc2idx, idx2lgc, lgc = _build_label_vocab("logic", data) - knw2idx, idx2knw, knw = _build_label_vocab("knowledge", data) - diag_data_dic = { - "sents1": sent1s, - "sents2": sent2s, - "targs": labels, - "idxs": idxs, - "lex_sem": lxs, - "pr_ar_str": pas, - "logic": lgc, - "knowledge": knw, - "ix_to_lex_sem_dic": idx2lxs, - "ix_to_pr_ar_str_dic": idx2pas, - "ix_to_logic_dic": idx2lgc, - "ix_to_knowledge_dic": idx2knw, - } - - self.ix_to_lex_sem_dic = diag_data_dic["ix_to_lex_sem_dic"] - self.ix_to_pr_ar_str_dic = diag_data_dic["ix_to_pr_ar_str_dic"] - self.ix_to_logic_dic = diag_data_dic["ix_to_logic_dic"] - self.ix_to_knowledge_dic = diag_data_dic["ix_to_knowledge_dic"] - - # Train, val, test splits are same. We only need one split but the code - # probably expects all splits to be present. - self.train_data_text = ( - diag_data_dic["sents1"], - diag_data_dic["sents2"], - diag_data_dic["targs"], - diag_data_dic["idxs"], - diag_data_dic["lex_sem"], - diag_data_dic["pr_ar_str"], - diag_data_dic["logic"], - diag_data_dic["knowledge"], - ) - self.val_data_text = self.train_data_text - self.test_data_text = self.train_data_text - self.sentences = self.train_data_text[0] + self.train_data_text[1] - log.info("\tFinished loading diagnostic data.") - - # TODO: use FastMatthews instead to save memory. - create_score_function(Correlation, "matthews", self.ix_to_lex_sem_dic, "lex_sem") - create_score_function(Correlation, "matthews", self.ix_to_pr_ar_str_dic, "pr_ar_str") - create_score_function(Correlation, "matthews", self.ix_to_logic_dic, "logic") - create_score_function(Correlation, "matthews", self.ix_to_knowledge_dic, "knowledge") - self._scorer_all_mcc = Correlation("matthews") # score all examples according to MCC - self._scorer_all_acc = CategoricalAccuracy() # score all examples according to acc - log.info("\tFinished creating score functions for diagnostic data.") - - -@register_task("winogender-diagnostic", rel_path="RTE/diagnostics", n_classes=2) -class WinogenderTask(GLUEDiagnosticTask): - """Supported winogender task """ - - def __init__(self, path, max_seq_len, name, n_classes, **kw): - super().__init__(path, max_seq_len, name, n_classes, **kw) - self.path = path - self.max_seq_len = max_seq_len - self.n_classes = n_classes - - self.train_data_text = None - self.val_data_text = None - self.test_data_text = None - self.acc_scorer = BooleanAccuracy() - self.gender_parity_scorer = GenderParity() - self.val_metric = "%s_accuracy" % name - - def load_data(self): - """ Process the datasets located at path. """ - targ_map = {"not_entailment": 0, "entailment": 1} - - self.train_data_text = load_pair_nli_jsonl( - os.path.join(self.path, "AX-g.jsonl"), self._tokenizer_name, self.max_seq_len, targ_map - ) - self.val_data_text = load_pair_nli_jsonl( - os.path.join(self.path, "AX-g.jsonl"), self._tokenizer_name, self.max_seq_len, targ_map - ) - self.test_data_text = load_pair_nli_jsonl( - os.path.join(self.path, "AX-g.jsonl"), self._tokenizer_name, self.max_seq_len, targ_map - ) - self.sentences = ( - self.train_data_text[0] - + self.train_data_text[1] - + self.val_data_text[0] - + self.val_data_text[1] - ) - log.info("\tFinished loading winogender (from SuperGLUE formatted data).") - - def process_split(self, split, indexers, model_preprocessing_interface): - def _make_instance(input1, input2, labels, idx, pair_id): - d = {} - d["sent1_str"] = MetadataField(" ".join(input1)) - if model_preprocessing_interface.model_flags["uses_pair_embedding"]: - inp = model_preprocessing_interface.boundary_token_fn(input1, input2) - d["inputs"] = sentence_to_text_field(inp, indexers) - d["sent2_str"] = MetadataField(" ".join(input2)) - else: - d["input1"] = sentence_to_text_field( - model_preprocessing_interface.boundary_token_fn(input1), indexers - ) - if input2: - d["input2"] = sentence_to_text_field( - model_preprocessing_interface.boundary_token_fn(input2), indexers - ) - d["sent2_str"] = MetadataField(" ".join(input2)) - d["labels"] = LabelField(labels, label_namespace="labels", skip_indexing=True) - d["idx"] = LabelField(idx, label_namespace="idxs_tags", skip_indexing=True) - d["pair_id"] = LabelField(pair_id, label_namespace="pair_id_tags", skip_indexing=True) - return Instance(d) - - instances = map(_make_instance, *split) - return instances # lazy iterator - - def get_metrics(self, reset=False): - return { - "accuracy": self.acc_scorer.get_metric(reset), - "gender_parity": self.gender_parity_scorer.get_metric(reset), - } - - def update_diagnostic_metrics(self, logits, labels, batch): - _, preds = logits.max(dim=1) - self.acc_scorer(preds, labels) - batch["preds"] = preds - # Convert batch to dict to fit gender_parity_scorer API. - batch_dict = [ - { - key: batch[key][index] - for key in batch.keys() - if key not in ["input1", "input2", "inputs"] - } - for index in range(len(batch["sent1_str"])) - ] - self.gender_parity_scorer(batch_dict) - - -@register_task("rte", rel_path="RTE/") -class RTETask(PairClassificationTask): - """ Task class for Recognizing Textual Entailment 1, 2, 3, 5 """ - - def __init__(self, path, max_seq_len, name, **kw): - super().__init__(name, n_classes=2, **kw) - self.path = path - self.max_seq_len = max_seq_len - - self.train_data_text = None - self.val_data_text = None - self.test_data_text = None - - def load_data(self): - """ Process the datasets located at path. """ - targ_map = {"not_entailment": 0, "entailment": 1} - self.train_data_text = load_tsv( - self._tokenizer_name, - os.path.join(self.path, "train.tsv"), - max_seq_len=self.max_seq_len, - label_fn=targ_map.__getitem__, - s1_idx=1, - s2_idx=2, - label_idx=3, - skip_rows=1, - ) - self.val_data_text = load_tsv( - self._tokenizer_name, - os.path.join(self.path, "dev.tsv"), - max_seq_len=self.max_seq_len, - label_fn=targ_map.__getitem__, - s1_idx=1, - s2_idx=2, - label_idx=3, - skip_rows=1, - ) - self.test_data_text = load_tsv( - self._tokenizer_name, - os.path.join(self.path, "test.tsv"), - max_seq_len=self.max_seq_len, - s1_idx=1, - s2_idx=2, - has_labels=False, - return_indices=True, - skip_rows=1, - ) - self.sentences = ( - self.train_data_text[0] - + self.train_data_text[1] - + self.val_data_text[0] - + self.val_data_text[1] - ) - log.info("\tFinished loading RTE (from GLUE formatted data).") - - -@register_task("rte-superglue", rel_path="RTE/") -class RTESuperGLUETask(RTETask): - """ Task class for Recognizing Textual Entailment 1, 2, 3, 5 - Uses JSONL format used by SuperGLUE""" - - def load_data(self): - """ Process the datasets located at path. """ - targ_map = {"not_entailment": 0, True: 1, False: 0, "entailment": 1} - - def _load_jsonl(data_file): - data = [json.loads(d) for d in open(data_file, encoding="utf-8")] - sent1s, sent2s, trgs, idxs = [], [], [], [] - for example in data: - sent1s.append( - tokenize_and_truncate( - self._tokenizer_name, example["premise"], self.max_seq_len - ) - ) - sent2s.append( - tokenize_and_truncate( - self._tokenizer_name, example["hypothesis"], self.max_seq_len - ) - ) - trg = targ_map[example["label"]] if "label" in example else 0 - trgs.append(trg) - idxs.append(example["idx"]) - return [sent1s, sent2s, trgs, idxs] - - self.train_data_text = _load_jsonl(os.path.join(self.path, "train.jsonl")) - self.val_data_text = _load_jsonl(os.path.join(self.path, "val.jsonl")) - self.test_data_text = _load_jsonl(os.path.join(self.path, "test.jsonl")) - - self.sentences = ( - self.train_data_text[0] - + self.train_data_text[1] - + self.val_data_text[0] - + self.val_data_text[1] - ) - log.info("\tFinished loading RTE (from SuperGLUE formatted data).") - - -@register_task("qnli", rel_path="QNLI/") -# second copy for different params -@register_task("qnli-alt", rel_path="QNLI/") -class QNLITask(PairClassificationTask): - """Task class for SQuAD NLI""" - - def __init__(self, path, max_seq_len, name, **kw): - super(QNLITask, self).__init__(name, n_classes=2, **kw) - self.path = path - self.max_seq_len = max_seq_len - - self.train_data_text = None - self.val_data_text = None - self.test_data_text = None - - def load_data(self): - """Load the data""" - targ_map = {"not_entailment": 0, "entailment": 1} - self.train_data_text = load_tsv( - self._tokenizer_name, - os.path.join(self.path, "train.tsv"), - max_seq_len=self.max_seq_len, - label_fn=targ_map.__getitem__, - s1_idx=1, - s2_idx=2, - label_idx=3, - skip_rows=1, - ) - self.val_data_text = load_tsv( - self._tokenizer_name, - os.path.join(self.path, "dev.tsv"), - max_seq_len=self.max_seq_len, - label_fn=targ_map.__getitem__, - s1_idx=1, - s2_idx=2, - label_idx=3, - skip_rows=1, - ) - self.test_data_text = load_tsv( - self._tokenizer_name, - os.path.join(self.path, "test.tsv"), - max_seq_len=self.max_seq_len, - s1_idx=1, - s2_idx=2, - has_labels=False, - return_indices=True, - skip_rows=1, - ) - self.sentences = ( - self.train_data_text[0] - + self.train_data_text[1] - + self.val_data_text[0] - + self.val_data_text[1] - ) - log.info("\tFinished loading QNLI.") - - -@register_task("wnli", rel_path="WNLI/") -class WNLITask(PairClassificationTask): - """Class for Winograd NLI task""" - - def __init__(self, path, max_seq_len, name, **kw): - super(WNLITask, self).__init__(name, n_classes=2, **kw) - self.path = path - self.max_seq_len = max_seq_len - - self.train_data_text = None - self.val_data_text = None - self.test_data_text = None - - def load_data(self): - """Load the data""" - self.train_data_text = load_tsv( - self._tokenizer_name, - os.path.join(self.path, "train.tsv"), - max_seq_len=self.max_seq_len, - s1_idx=1, - s2_idx=2, - label_idx=3, - skip_rows=1, - ) - self.val_data_text = load_tsv( - self._tokenizer_name, - os.path.join(self.path, "dev.tsv"), - max_seq_len=self.max_seq_len, - s1_idx=1, - s2_idx=2, - label_idx=3, - skip_rows=1, - ) - self.test_data_text = load_tsv( - self._tokenizer_name, - os.path.join(self.path, "test.tsv"), - max_seq_len=self.max_seq_len, - s1_idx=1, - s2_idx=2, - has_labels=False, - return_indices=True, - skip_rows=1, - ) - self.sentences = ( - self.train_data_text[0] - + self.train_data_text[1] - + self.val_data_text[0] - + self.val_data_text[1] - ) - log.info("\tFinished loading Winograd.") - - -@register_task("joci", rel_path="JOCI/") -class JOCITask(PairOrdinalRegressionTask): - """Class for JOCI ordinal regression task""" - - def __init__(self, path, max_seq_len, name, **kw): - super(JOCITask, self).__init__(name, **kw) - self.path = path - self.max_seq_len = max_seq_len - - self.train_data_text = None - self.val_data_text = None - self.test_data_text = None - - def load_data(self): - self.train_data_text = load_tsv( - self._tokenizer_name, - os.path.join(self.path, "train.tsv"), - max_seq_len=self.max_seq_len, - skip_rows=1, - s1_idx=0, - s2_idx=1, - label_idx=2, - ) - self.val_data_text = load_tsv( - self._tokenizer_name, - os.path.join(self.path, "dev.tsv"), - max_seq_len=self.max_seq_len, - skip_rows=1, - s1_idx=0, - s2_idx=1, - label_idx=2, - ) - self.test_data_text = load_tsv( - self._tokenizer_name, - os.path.join(self.path, "test.tsv"), - max_seq_len=self.max_seq_len, - skip_rows=1, - s1_idx=0, - s2_idx=1, - label_idx=2, - ) - self.sentences = ( - self.train_data_text[0] - + self.train_data_text[1] - + self.val_data_text[0] - + self.val_data_text[1] - ) - log.info("\tFinished loading JOCI data.") - - -@register_task("wiki103-classif", rel_path="WikiText103/") -class Wiki103Classification(PairClassificationTask): - """Pair Classificaiton Task using Wiki103""" - - def __init__(self, path, max_seq_len, name, **kw): - super().__init__(name, n_classes=2, **kw) - self.scorer2 = None - self.val_metric = "%s_accuracy" % self.name - self.val_metric_decreases = False - self.files_by_split = { - "train": os.path.join(path, "train.sentences.txt"), - "val": os.path.join(path, "valid.sentences.txt"), - "test": os.path.join(path, "test.sentences.txt"), - } - self.max_seq_len = max_seq_len - self.min_seq_len = 0 - - def load_data(self): - # Data is exposed as iterable: no preloading - pass - - def get_split_text(self, split: str): - """ Get split text as iterable of records. - Split should be one of 'train', 'val', or 'test'. - """ - return self.load_data_for_path(self.files_by_split[split]) - - def load_data_for_path(self, path): - """ Rather than return a whole list of examples, stream them - See WikiTextLMTask for an explanation of the preproc""" - nonatomics_toks = [UNK_TOK_ALLENNLP, ""] - with open(path) as txt_fh: - for row in txt_fh: - toks = row.strip() - if not toks: - continue - sent = atomic_tokenize( - toks, - UNK_TOK_ATOMIC, - nonatomics_toks, - self.max_seq_len, - tokenizer_name=self._tokenizer_name, - ) - if sent.count("=") >= 2 or len(toks) < self.min_seq_len + 2: - continue - yield sent - - def get_sentences(self) -> Iterable[Sequence[str]]: - """ Yield sentences, used to compute vocabulary. """ - for split in self.files_by_split: - # Don't use test set for vocab building. - if split.startswith("test"): - continue - path = self.files_by_split[split] - for sent in self.load_data_for_path(path): - yield sent - - def process_split( - self, split, indexers, model_preprocessing_interface - ) -> Iterable[Type[Instance]]: - """ Process a language modeling split. Split is a single list of sentences here. """ - - def _make_instance(input1, input2, labels): - d = {} - d["input1"] = sentence_to_text_field( - model_preprocessing_interface.boundary_token_fn(input1), indexers - ) - d["input2"] = sentence_to_text_field( - model_preprocessing_interface.boundary_token_fn(input2), indexers - ) - d["labels"] = LabelField(labels, label_namespace="labels", skip_indexing=True) - return Instance(d) - - first = True - for sent in split: - if first: - prev_sent = sent - first = False - continue - yield _make_instance(prev_sent, sent, 1) - prev_sent = sent - - def count_examples(self): - """ Compute here b/c we're streaming the sentences. """ - example_counts = {} - for split, split_path in self.files_by_split.items(): - # pair sentence # = sent # - 1 - example_counts[split] = sum(1 for line in open(split_path)) - 1 - self.example_counts = example_counts - - -# Task class for DisSent with Wikitext 103 only considering clauses from within a single sentence -# Data sets should be prepared as described in Nie, Bennett, and Goodman (2017) -@register_task("dissentwiki", rel_path="DisSent/wikitext/", prefix="wikitext.dissent.single_sent") -# Task class for DisSent with Wikitext 103 considering clauses from within a single sentence -# or across two sentences. -# Data sets should be prepared as described in Nie, Bennett, and Goodman (2017) -@register_task("dissentwikifullbig", rel_path="DisSent/wikitext/", prefix="wikitext.dissent.big") -class DisSentTask(PairClassificationTask): - """ Task class for DisSent, dataset agnostic. - Based on Nie, Bennett, and Goodman (2017), but with different datasets. - """ - - def __init__(self, path, max_seq_len, prefix, name, **kw): - """ There are 8 classes because there are 8 discourse markers in - the dataset (and, but, because, if, when, before, though, so) - """ - super().__init__(name, n_classes=8, **kw) - self.max_seq_len = max_seq_len - self.files_by_split = { - "train": os.path.join(path, "%s.train" % prefix), - "val": os.path.join(path, "%s.valid" % prefix), - "test": os.path.join(path, "%s.test" % prefix), - } - - def load_data(self): - # Data is exposed as iterable: no preloading - pass - - def get_split_text(self, split: str): - """ Get split text as iterable of records. - - Split should be one of 'train', 'val', or 'test'. - """ - return self.load_data_for_path(self.files_by_split[split]) - - def load_data_for_path(self, path): - """ Load data """ - with open(path, "r") as txt_fh: - for row in txt_fh: - row = row.strip().split("\t") - if len(row) != 3 or not (row[0] and row[1] and row[2]): - continue - sent1 = tokenize_and_truncate(self._tokenizer_name, row[0], self.max_seq_len) - sent2 = tokenize_and_truncate(self._tokenizer_name, row[1], self.max_seq_len) - targ = int(row[2]) - yield (sent1, sent2, targ) - - def get_sentences(self) -> Iterable[Sequence[str]]: - """ Yield sentences, used to compute vocabulary. """ - for split in self.files_by_split: - """ Don't use test set for vocab building. """ - if split.startswith("test"): - continue - path = self.files_by_split[split] - for sent1, sent2, _ in self.load_data_for_path(path): - yield sent1 - yield sent2 - - def count_examples(self): - """ Compute the counts here b/c we're streaming the sentences. """ - example_counts = {} - for split, split_path in self.files_by_split.items(): - example_counts[split] = sum(1 for line in open(split_path)) - self.example_counts = example_counts - - def process_split( - self, split, indexers, model_preprocessing_interface - ) -> Iterable[Type[Instance]]: - """ Process split text into a list of AllenNLP Instances. """ - - def _make_instance(input1, input2, labels): - d = {} - if model_preprocessing_interface.model_flags["uses_pair_embedding"]: - inp = model_preprocessing_interface.boundary_token_fn( - input1, input2 - ) # drop leading [CLS] token - d["inputs"] = sentence_to_text_field(inp, indexers) - else: - d["input1"] = sentence_to_text_field( - model_preprocessing_interface.boundary_token_fn(input1), indexers - ) - d["input2"] = sentence_to_text_field( - model_preprocessing_interface.boundary_token_fn(input2), indexers - ) - d["labels"] = LabelField(labels, label_namespace="labels", skip_indexing=True) - return Instance(d) - - for sent1, sent2, trg in split: - yield _make_instance(sent1, sent2, trg) - - -@register_task("recast-puns", rel_path="DNC/recast_puns_data") -@register_task("recast-ner", rel_path="DNC/recast_ner_data") -@register_task("recast-verbnet", rel_path="DNC/recast_verbnet_data") -@register_task("recast-verbcorner", rel_path="DNC/recast_verbcorner_data") -@register_task("recast-sentiment", rel_path="DNC/recast_sentiment_data") -@register_task("recast-factuality", rel_path="DNC/recast_factuality_data") -@register_task("recast-winogender", rel_path="DNC/manually-recast-winogender") -@register_task("recast-lexicosyntax", rel_path="DNC/lexicosyntactic_recasted") -@register_task("recast-kg", rel_path="DNC/kg-relations") -class RecastNLITask(PairClassificationTask): - """ Task class for NLI Recast Data""" - - def __init__(self, path, max_seq_len, name, **kw): - super(RecastNLITask, self).__init__(name, n_classes=2, **kw) - self.path = path - self.max_seq_len = max_seq_len - - self.train_data_text = None - self.val_data_text = None - self.test_data_text = None - - def load_data(self): - self.train_data_text = load_tsv( - self._tokenizer_name, - os.path.join(self.path, "train.tsv"), - max_seq_len=self.max_seq_len, - s1_idx=1, - s2_idx=2, - skip_rows=0, - label_idx=3, - ) - self.val_data_text = load_tsv( - self._tokenizer_name, - os.path.join(self.path, "dev.tsv"), - max_seq_len=self.max_seq_len, - s1_idx=0, - s2_idx=1, - skip_rows=0, - label_idx=3, - ) - self.test_data_text = load_tsv( - self._tokenizer_name, - os.path.join(self.path, "test.tsv"), - max_seq_len=self.max_seq_len, - s1_idx=1, - s2_idx=2, - skip_rows=0, - label_idx=3, - ) - self.sentences = ( - self.train_data_text[0] - + self.train_data_text[1] - + self.val_data_text[0] - + self.val_data_text[1] - ) - log.info("\tFinished loading recast probing data.") - - -class TaggingTask(Task): - """ Generic tagging task, one tag per word """ - - def __init__(self, name, num_tags, **kw): - super().__init__(name, **kw) - assert num_tags > 0 - self.num_tags = num_tags - self.scorer1 = CategoricalAccuracy() - self.scorers = [self.scorer1] - self.val_metric = "%s_accuracy" % self.name - self.val_metric_decreases = False - self.all_labels = [str(i) for i in range(self.num_tags)] - self._label_namespace = self.name + "_tags" - self.target_indexer = {"words": SingleIdTokenIndexer(namespace=self._label_namespace)} - - self.train_data_text = None - self.val_data_text = None - self.test_data_text = None - - def get_metrics(self, reset=False): - """Get metrics specific to the task""" - acc = self.scorer1.get_metric(reset) - return {"accuracy": acc} - - def get_all_labels(self) -> List[str]: - return self.all_labels - - def update_metrics(self, out, batch): - logits = out["logits"] - labels = batch["labels"] - assert len(self.get_scorers()) > 0, "Please specify a score metric" - for scorer in self.get_scorers(): - scorer(logits, labels) - - -@register_task("ccg", rel_path="CCG/") -class CCGTaggingTask(TaggingTask): - """ CCG supertagging as a task. - Using the supertags from CCGbank. """ - - def __init__(self, path, max_seq_len, name, tokenizer_name, **kw): - """ There are 1363 supertags in CCGBank without introduced token. """ - from jiant.huggingface_transformers_interface import input_module_uses_transformers - - subword_tokenization = input_module_uses_transformers(tokenizer_name) - super().__init__( - name, 1363 + int(subword_tokenization), tokenizer_name=tokenizer_name, **kw - ) - self.path = path - self.INTRODUCED_TOKEN = "1363" - self.subword_tokenization = subword_tokenization - self.max_seq_len = max_seq_len - self.train_data_text = None - self.val_data_text = None - self.test_data_text = None - - def update_metrics(self, out, batch): - logits, labels = out["logits"], out["labels"] - for scorer in self.get_scorers(): - scorer(logits, labels) - - def process_split( - self, split, indexers, model_preprocessing_interface - ) -> Iterable[Type[Instance]]: - """ Process a CCG tagging task """ - - def _make_instance(input1, input2, target, mask): - d = {} - d["inputs"] = sentence_to_text_field( - model_preprocessing_interface.boundary_token_fn(input1), indexers - ) - d["sent1_str"] = MetadataField(" ".join(input1)) - d["targs"] = sentence_to_text_field(target, self.target_indexer) - d["mask"] = MultiLabelField( - mask, label_namespace="idx_tags", skip_indexing=True, num_labels=511 - ) - return Instance(d) - - split = list(split) - split[1] = itertools.repeat(None) - - instances = map(_make_instance, *split) - return instances - - def load_data(self): - tr_data = load_tsv( - self._tokenizer_name, - os.path.join(self.path, "ccg.train." + self._tokenizer_name), - max_seq_len=self.max_seq_len, - s1_idx=1, - s2_idx=None, - label_idx=2, - skip_rows=1, - delimiter="\t", - label_fn=lambda t: t.split(" "), - ) - val_data = load_tsv( - self._tokenizer_name, - os.path.join(self.path, "ccg.dev." + self._tokenizer_name), - max_seq_len=self.max_seq_len, - s1_idx=1, - s2_idx=None, - label_idx=2, - skip_rows=1, - delimiter="\t", - label_fn=lambda t: t.split(" "), - ) - te_data = load_tsv( - self._tokenizer_name, - os.path.join(self.path, "ccg.test." + self._tokenizer_name), - max_seq_len=self.max_seq_len, - s1_idx=1, - s2_idx=None, - label_idx=2, - skip_rows=1, - delimiter="\t", - has_labels=False, - ) - - # Get the mask for each sentence, where the mask is whether or not - # the token was split off by tokenization. We want to only count the first - # sub-piece in the BERT tokenization in the loss and score, following Devlin's NER - # experiment - # [BERT: Pretraining of Deep Bidirectional Transformers for Language Understanding] - # (https://arxiv.org/abs/1810.04805) - if self.subword_tokenization: - import numpy.ma as ma - - masks = [] - for dataset in [tr_data, val_data]: - dataset_mask = [] - for i in range(len(dataset[2])): - mask = ma.getmask( - ma.masked_where( - np.array(dataset[2][i]) != self.INTRODUCED_TOKEN, - np.array(dataset[2][i]), - ) - ) - mask_indices = np.where(mask)[0].tolist() - dataset_mask.append(mask_indices) - masks.append(dataset_mask) - - # mock labels for test data (tagging) - te_targs = [["0"] * len(x) for x in te_data[0]] - te_mask = [list(range(len(x))) for x in te_data[0]] - self.train_data_text = list(tr_data) + [masks[0]] - self.val_data_text = list(val_data) + [masks[1]] - self.test_data_text = list(te_data[:2]) + [te_targs] + [te_mask] - self.sentences = self.train_data_text[0] + self.val_data_text[0] - log.info("\tFinished loading CCGTagging data.") - - -class SpanClassificationTask(Task): - """ - Generic class for span tasks. - Acts as a classifier, but with multiple targets for each input text. - Targets are of the form (span1, span2,..., span_n, label), where the spans are - half-open token intervals [i, j). - The number of spans is constant across examples. - """ - - def __init__( - self, - path: str, - max_seq_len: int, - name: str, - label_file: str = None, - files_by_split: Dict[str, str] = None, - num_spans: int = 2, - **kw, - ): - """ - Construct a span task. - @register_task. - - Parameters - --------------------- - path: data directory - max_seq_len: maximum sequence length (currently ignored) - name: task name - label_file: relative path to labels file - - should be a line-delimited file where each line is a value the - label can take. - files_by_split: split name ('train', 'val', 'test') mapped to - relative filenames (e.g. 'train': 'train.json') - """ - super().__init__(name, **kw) - - assert label_file is not None - assert files_by_split is not None - self._files_by_split = { - split: os.path.join(path, fname) for split, fname in files_by_split.items() - } - self.num_spans = num_spans - self.max_seq_len = max_seq_len - - self._iters_by_split = None - - self.label_file = os.path.join(path, label_file) - self.n_classes = None - self._label_namespace = self.name + "_labels" - - self.acc_scorer = BooleanAccuracy() # binary accuracy - self.f1_scorer = F1Measure(positive_label=1) # binary F1 overall - self.scorers = [self.acc_scorer, self.f1_scorer] - self.val_metric = "%s_f1" % self.name - self.val_metric_decreases = False - - def _stream_records(self, filename): - """ - Helper function for loading the data, which is in json format and - checks if it has targets. - """ - skip_ctr = 0 - total_ctr = 0 - for record in utils.load_json_data(filename): - total_ctr += 1 - if not record.get("targets", None): - skip_ctr += 1 - continue - yield record - log.info( - "Read=%d, Skip=%d, Total=%d from %s", - total_ctr - skip_ctr, - skip_ctr, - total_ctr, - filename, - ) - - def get_split_text(self, split: str): - """ - Get split text as iterable of records. - Split should be one of 'train', 'val', or 'test'. - """ - return self._iters_by_split[split] - - def get_num_examples(self, split_text): - """ - Return number of examples in the result of get_split_text. - Subclass can override this if data is not stored in column format. - """ - return len(split_text) - - def _make_span_field(self, s, text_field, offset=1): - # AllenNLP span extractor expects inclusive span indices - # so minus 1 at the end index. - return SpanField(s[0] + offset, s[1] - 1 + offset, text_field) - - def make_instance(self, record, idx, indexers, model_preprocessing_interface) -> Type[Instance]: - """Convert a single record to an AllenNLP Instance.""" - tokens = record["text"].split() - tokens, offset = model_preprocessing_interface.boundary_token_fn(tokens, get_offset=True) - text_field = sentence_to_text_field(tokens, indexers) - - example = {} - example["idx"] = MetadataField(idx) - - example["input1"] = text_field - - for i in range(self.num_spans): - example["span" + str(i + 1) + "s"] = ListField( - [self._make_span_field(record["target"]["span" + str(i + 1)], text_field, offset)] - ) - example["labels"] = LabelField( - record["label"], label_namespace="labels", skip_indexing=True - ) - return Instance(example) - - def process_split( - self, records, indexers, model_preprocessing_interface - ) -> Iterable[Type[Instance]]: - """ Process split text into a list of AllenNLP Instances. """ - - def _map_fn(r, idx): - return self.make_instance(r, idx, indexers, model_preprocessing_interface) - - return map(_map_fn, records, itertools.count()) - - def get_sentences(self) -> Iterable[Sequence[str]]: - """ Yield sentences, used to compute vocabulary. """ - for split, iter in self._iters_by_split.items(): - # Don't use test set for vocab building. - if split.startswith("test"): - continue - for record in iter: - yield record["text"].split() - - def get_metrics(self, reset=False): - """Get metrics specific to the task""" - metrics = {} - metrics["acc"] = self.acc_scorer.get_metric(reset) - precision, recall, f1 = self.f1_scorer.get_metric(reset) - metrics["precision"] = precision - metrics["recall"] = recall - metrics["f1"] = f1 - return metrics - - def update_metrics(self, out, batch): - logits = out["logits"] - labels = batch["labels"] - assert len(self.get_scorers()) > 0, "Please specify a score metric" - for scorer in self.get_scorers(): - scorer(logits, labels) - - -@register_task("commitbank", rel_path="CB/") -class CommitmentTask(PairClassificationTask): - """ NLI-formatted task detecting speaker commitment. - Data and more info at github.com/mcdm/CommitmentBank/ - Paper forthcoming. """ - - def __init__(self, path, max_seq_len, name, **kw): - """ We use three F1 trackers, one for each class to compute multi-class F1 """ - super().__init__(name, n_classes=3, **kw) - self.path = path - self.max_seq_len = max_seq_len - - self.train_data_text = None - self.val_data_text = None - self.test_data_text = None - - self.scorer2 = F1Measure(0) - self.scorer3 = F1Measure(1) - self.scorer4 = F1Measure(2) - self.scorers = [self.scorer1, self.scorer2, self.scorer3, self.scorer4] - self.val_metric = "%s_f1" % name - - def load_data(self): - """Process the dataset located at each data file. - The target needs to be split into tokens because - it is a sequence (one tag per input token). """ - targ_map = {"neutral": 0, "entailment": 1, "contradiction": 2} - - def _load_data(data_file): - data = [json.loads(l) for l in open(data_file, encoding="utf-8").readlines()] - sent1s, sent2s, targs, idxs = [], [], [], [] - for example in data: - sent1s.append( - tokenize_and_truncate( - self._tokenizer_name, example["premise"], self.max_seq_len - ) - ) - sent2s.append( - tokenize_and_truncate( - self._tokenizer_name, example["hypothesis"], self.max_seq_len - ) - ) - trg = targ_map[example["label"]] if "label" in example else 0 - targs.append(trg) - idxs.append(example["idx"]) - assert len(sent1s) == len(sent2s) == len(targs) == len(idxs), "Error processing CB data" - return [sent1s, sent2s, targs, idxs] - - self.train_data_text = _load_data(os.path.join(self.path, "train.jsonl")) - self.val_data_text = _load_data(os.path.join(self.path, "val.jsonl")) - self.test_data_text = _load_data(os.path.join(self.path, "test.jsonl")) - self.sentences = ( - self.train_data_text[0] - + self.val_data_text[0] - + self.train_data_text[1] - + self.val_data_text[1] - ) - - log.info("\tFinished loading CommitmentBank data.") - - def get_metrics(self, reset=False): - """Get metrics specific to the task. - - scorer1 tracks accuracy - - scorers{2,3,4} compute class-specific F1, - and we macro-average to get multi-class F1""" - acc = self.scorer1.get_metric(reset) - pcs1, rcl1, f11 = self.scorer2.get_metric(reset) - pcs2, rcl2, f12 = self.scorer3.get_metric(reset) - pcs3, rcl3, f13 = self.scorer4.get_metric(reset) - pcs = (pcs1 + pcs2 + pcs3) / 3 - rcl = (rcl1 + rcl2 + rcl3) / 3 - f1 = (f11 + f12 + f13) / 3 - return {"accuracy": acc, "f1": f1, "precision": pcs, "recall": rcl} - - -@register_task("wic", rel_path="WiC/") -class WiCTask(PairClassificationTask): - """ Task class for Words in Context. """ - - def __init__(self, path, max_seq_len, name, **kw): - super().__init__(name, n_classes=2, **kw) - self.path = path - self.max_seq_len = max_seq_len - - self.train_data_text = None - self.val_data_text = None - self.test_data_text = None - - self.scorer1 = CategoricalAccuracy() - self.scorer2 = F1Measure(1) - self.scorers = [self.scorer1, self.scorer2] - self.val_metric = "%s_accuracy" % name - self.val_metric_decreases = False - - def load_data(self): - """Process the dataset located at data_file.""" - - trg_map = {"true": 1, "false": 0, True: 1, False: 0} - - aligner_fn = get_aligner_fn(self._tokenizer_name) - - def _process_preserving_word(sent, word): - """ Find out the index of the [first] instance of the word in the original sentence, - and project the span containing marked word to the span containing tokens created from - the marked word. """ - token_aligner, sent_tok = aligner_fn(sent) - raw_start_idx = len(sent.split(word)[0].split(" ")) - 1 - # after spliting, there could be three cases, 1. a tailing space, 2. characters in front - # of the keyword, 3. the sentence starts with the keyword - raw_end_idx = len(word.split()) + raw_start_idx - start_idx, end_idx = token_aligner.project_span(raw_start_idx, raw_end_idx) - assert end_idx > start_idx, "Invalid marked word indices. Something is wrong." - return sent_tok, start_idx, end_idx - - def _load_split(data_file): - sents1, sents2, idxs1, idxs2, trgs, idxs = [], [], [], [], [], [] - with open(data_file, "r") as data_fh: - for row in data_fh: - row = json.loads(row) - sent1 = row["sentence1"] - sent2 = row["sentence2"] - word1 = sent1[row["start1"] : row["end1"]] - word2 = sent2[row["start2"] : row["end2"]] - sent1, start1, end1 = _process_preserving_word(sent1, word1) - sent2, start2, end2 = _process_preserving_word(sent2, word2) - sents1.append(sent1) - sents2.append(sent2) - idxs1.append((start1, end1)) - idxs2.append((start2, end2)) - trg = trg_map[row["label"]] if "label" in row else 0 - trgs.append(trg) - idxs.append(row["idx"]) - assert ( - "version" in row and row["version"] == 1.1 - ), "WiC version is not v1.1; examples indices are likely incorrect and data " - "is likely pre-tokenized. Please re-download the data from " - "super.gluebenchmark.com." - return [sents1, sents2, idxs1, idxs2, trgs, idxs] - - self.train_data_text = _load_split(os.path.join(self.path, "train.jsonl")) - self.val_data_text = _load_split(os.path.join(self.path, "val.jsonl")) - self.test_data_text = _load_split(os.path.join(self.path, "test.jsonl")) - self.sentences = ( - self.train_data_text[0] - + self.train_data_text[1] - + self.val_data_text[0] - + self.val_data_text[1] - ) - log.info("\tFinished loading WiC data.") - - def process_split(self, split, indexers, model_preprocessing_interface): - """ - Convert a dataset of sentences into padded sequences of indices. Shared - across several classes. - - """ - # check here if using bert to avoid passing model info to tasks - - def _make_instance(input1, input2, idxs1, idxs2, labels, idx): - d = {} - d["sent1_str"] = MetadataField(" ".join(input1)) - d["sent2_str"] = MetadataField(" ".join(input2)) - if model_preprocessing_interface.model_flags["uses_pair_embedding"]: - inp, offset1, offset2 = model_preprocessing_interface.boundary_token_fn( - input1, input2, get_offset=True - ) - d["inputs"] = sentence_to_text_field(inp[: self.max_seq_len], indexers) - else: - inp1, offset1 = model_preprocessing_interface.boundary_token_fn( - input1, get_offset=True - ) - inp2, offset2 = model_preprocessing_interface.boundary_token_fn( - input2, get_offset=True - ) - d["input1"] = sentence_to_text_field(inp1[: self.max_seq_len], indexers) - d["input2"] = sentence_to_text_field(inp2[: self.max_seq_len], indexers) - d["idx1"] = ListField( - [ - NumericField(i) - for i in range( - min(idxs1[0] + offset1, self.max_seq_len - 1), - min(idxs1[1] + offset1, self.max_seq_len), - ) - ] - ) - d["idx2"] = ListField( - [ - NumericField(i) - for i in range( - min(idxs2[0] + offset2, self.max_seq_len - 1), - min(idxs2[1] + offset2, self.max_seq_len), - ) - ] - ) - d["labels"] = LabelField(labels, label_namespace="labels", skip_indexing=True) - d["idx"] = LabelField(idx, label_namespace="idxs_tags", skip_indexing=True) - - return Instance(d) - - # Map over columns: input1, (input2), labels, idx - instances = map(_make_instance, *split) - return instances # lazy iterator - - def get_metrics(self, reset=False): - """Get metrics specific to the task""" - acc = self.scorer1.get_metric(reset) - pcs, rcl, f1 = self.scorer2.get_metric(reset) - return {"accuracy": acc, "f1": f1, "precision": pcs, "recall": rcl} - - -class MultipleChoiceTask(Task): - """ Generic task class for a multiple choice - where each example consists of a question and - a (possibly variable) number of possible answers""" - - def update_metrics(self, out, batch): - logits = out["logits"] - labels = batch["label"] - assert len(self.get_scorers()) > 0, "Please specify a score metric" - for scorer in self.get_scorers(): - scorer(logits, labels) - - -@register_task("socialiqa", rel_path="SocialIQA/") -class SocialIQATask(MultipleChoiceTask): - """ Task class for SocialIQA. - Paper: https://homes.cs.washington.edu/~msap/pdfs/sap2019socialIQa.pdf - Website and data: https://maartensap.github.io/social-iqa/ - """ - - def __init__(self, path, max_seq_len, name, **kw): - super().__init__(name, **kw) - self.path = path - self.max_seq_len = max_seq_len - - self.train_data_text = None - self.val_data_text = None - self.test_data_text = None - - self.scorer1 = CategoricalAccuracy() - self.scorers = [self.scorer1] - self.val_metric = "%s_accuracy" % name - self.val_metric_decreases = False - self.n_choices = 3 - self._label_namespace = self.name + "_tags" - - def get_all_labels(self): - return ["A", "B", "C", "D"] - - def load_data(self): - """ Process the dataset located at path. """ - - def _load_split(data_file): - contexts, questions, choices, targs = [], [], [], [] - data = [json.loads(l) for l in open(data_file, encoding="utf-8")] - for example in data: - context = example["context"] - choice1 = example["answerA"] - choice2 = example["answerB"] - choice3 = example["answerC"] - question = example["question"] - choice = [ - tokenize_and_truncate(self._tokenizer_name, choice, self.max_seq_len) - for choice in [choice1, choice2, choice3] - ] - targ = example["correct"] if "correct" in example else 0 - contexts.append( - tokenize_and_truncate(self._tokenizer_name, context, self.max_seq_len) - ) - choices.append(choice) - questions.append( - tokenize_and_truncate(self._tokenizer_name, question, self.max_seq_len) - ) - targs.append(targ) - return [contexts, choices, questions, targs] - - self.train_data_text = _load_split(os.path.join(self.path, "socialIQa_v1.4_trn.jsonl")) - self.val_data_text = _load_split(os.path.join(self.path, "socialIQa_v1.4_dev.jsonl")) - self.test_data_text = _load_split(os.path.join(self.path, "socialIQa_v1.4_tst.jsonl")) - self.sentences = ( - self.train_data_text[0] - + self.val_data_text[0] - + [choice for choices in self.train_data_text[1] for choice in choices] - + [choice for choices in self.val_data_text[1] for choice in choices] - ) - log.info("\tFinished loading SocialIQA data.") - - def process_split( - self, split, indexers, model_preprocessing_interface - ) -> Iterable[Type[Instance]]: - """ Process split text into a list of AllenNLP Instances. """ - - def _make_instance(context, choices, question, label, idx): - d = {} - d["question_str"] = MetadataField(" ".join(context)) - if not model_preprocessing_interface.model_flags["uses_pair_embedding"]: - d["question"] = sentence_to_text_field( - model_preprocessing_interface.boundary_token_fn(context), indexers - ) - for choice_idx, choice in enumerate(choices): - inp = ( - model_preprocessing_interface.boundary_token_fn(context, question + choice) - if model_preprocessing_interface.model_flags["uses_pair_embedding"] - else model_preprocessing_interface.boundary_token_fn(choice) - ) - d["choice%d" % choice_idx] = sentence_to_text_field(inp, indexers) - d["choice%d_str" % choice_idx] = MetadataField(" ".join(choice)) - d["label"] = LabelField(label, label_namespace=self._label_namespace) - d["idx"] = LabelField(idx, label_namespace="idxs_tags", skip_indexing=True) - return Instance(d) - - split = list(split) - if len(split) < 5: - split.append(itertools.count()) - instances = map(_make_instance, *split) - return instances - - def get_metrics(self, reset=False): - """Get metrics specific to the task""" - acc = self.scorer1.get_metric(reset) - return {"accuracy": acc} - - -class SpanPredictionTask(Task): - """ Generic task class for predicting a span """ - - n_classes = 2 - - def update_metrics(self, out, batch): - batch_size = len(out["logits"]["span_start"]) - logits_dict = out["logits"] - pred_span_start = torch.argmax(logits_dict["span_start"], dim=1).cpu().numpy() - pred_span_end = torch.argmax(logits_dict["span_end"], dim=1).cpu().numpy() - - pred_str_list = self.get_pred_str( - out["logits"], batch, batch_size, pred_span_start, pred_span_end - ) - gold_str_list = batch["answer_str"] - - """ A batch of logits+answer strings and the questions they go with """ - self.f1_metric(pred_str_list=pred_str_list, gold_str_list=gold_str_list) - self.em_metric(pred_str_list=pred_str_list, gold_str_list=gold_str_list) - - def get_pred_str(self, preds, batch, batch_size, pred_span_start, pred_span_end): - """ - For span prediction, we compute metrics based on span strings. This function - gets the span string based on start and end index predictions. - - """ - pred_str_list = [] - for i in range(batch_size): - - # Adjust for start_offset (e.g. [CLS] tokens). - pred_span_start_i = pred_span_start[i] - batch["start_offset"][i] - pred_span_end_i = pred_span_end[i] - batch["start_offset"][i] - - # Ensure that predictions fit within the range of valid tokens - pred_span_start_i = min( - pred_span_start_i, len(batch["space_processed_token_map"][i]) - 1 - ) - pred_span_end_i = min( - max(pred_span_end_i, pred_span_start_i + 1), - len(batch["space_processed_token_map"][i]) - 1, - ) - - # space_processed_token_map is a list of tuples - # (space_token, processed_token (e.g. BERT), space_token_index) - # The assumption is that each space_token corresponds to multiple processed_tokens. - # After we get the corresponding start/end space_token_indices, we can do " ".join - # to get the corresponding string that is definitely within the original input. - # One constraint here is that our predictions can only go up to a the granularity of - # space_tokens. This is not so bad because SQuAD-style scripts also remove punctuation. - pred_char_span_start = batch["space_processed_token_map"][i][pred_span_start_i][2] - pred_char_span_end = batch["space_processed_token_map"][i][pred_span_end_i][2] - pred_str_list.append( - " ".join( - batch["passage_str"][i].split()[pred_char_span_start:pred_char_span_end] - ).strip() - ) - return pred_str_list - - def handle_preds(self, preds, batch): - batch_size = len(preds["span_start"]) - preds["span_str"] = self.get_pred_str( - preds, batch, batch_size, preds["span_start"], preds["span_end"] - ) - return preds - - -@register_task("copa", rel_path="COPA/") -class COPATask(MultipleChoiceTask): - """ Task class for Choice of Plausible Alternatives Task. """ - - def __init__(self, path, max_seq_len, name, **kw): - super().__init__(name, **kw) - self.path = path - self.max_seq_len = max_seq_len - - self.train_data_text = None - self.val_data_text = None - self.test_data_text = None - - self.scorer1 = CategoricalAccuracy() - self.scorers = [self.scorer1] - self.val_metric = "%s_accuracy" % name - self.val_metric_decreases = False - self.n_choices = 2 - - def load_data(self): - """ Process the dataset located at path. """ - - def _load_split(data_file): - contexts, questions, choicess, targs = [], [], [], [] - data = [json.loads(l) for l in open(data_file, encoding="utf-8")] - for example in data: - context = example["premise"] - choice1 = example["choice1"] - choice2 = example["choice2"] - question = example["question"] - question = ( - "What was the cause of this?" - if question == "cause" - else "What happened as a result?" - ) - choices = [ - tokenize_and_truncate(self._tokenizer_name, choice, self.max_seq_len) - for choice in [choice1, choice2] - ] - targ = example["label"] if "label" in example else 0 - contexts.append( - tokenize_and_truncate(self._tokenizer_name, context, self.max_seq_len) - ) - choicess.append(choices) - questions.append( - tokenize_and_truncate(self._tokenizer_name, question, self.max_seq_len) - ) - targs.append(targ) - return [contexts, choicess, questions, targs] - - self.train_data_text = _load_split(os.path.join(self.path, "train.jsonl")) - self.val_data_text = _load_split(os.path.join(self.path, "val.jsonl")) - self.test_data_text = _load_split(os.path.join(self.path, "test.jsonl")) - self.sentences = ( - self.train_data_text[0] - + self.val_data_text[0] - + [choice for choices in self.train_data_text[1] for choice in choices] - + [choice for choices in self.val_data_text[1] for choice in choices] - ) - log.info("\tFinished loading COPA (as QA) data.") - - def process_split( - self, split, indexers, model_preprocessing_interface - ) -> Iterable[Type[Instance]]: - """ Process split text into a list of AllenNLP Instances. """ - - def _make_instance(context, choices, question, label, idx): - d = {} - d["question_str"] = MetadataField(" ".join(context)) - if not model_preprocessing_interface.model_flags["uses_pair_embedding"]: - d["question"] = sentence_to_text_field( - model_preprocessing_interface.boundary_token_fn(context), indexers - ) - for choice_idx, choice in enumerate(choices): - inp = ( - model_preprocessing_interface.boundary_token_fn(context, question + choice) - if model_preprocessing_interface.model_flags["uses_pair_embedding"] - else model_preprocessing_interface.boundary_token_fn(choice) - ) - d["choice%d" % choice_idx] = sentence_to_text_field(inp, indexers) - d["choice%d_str" % choice_idx] = MetadataField(" ".join(choice)) - d["label"] = LabelField(label, label_namespace="labels", skip_indexing=True) - d["idx"] = LabelField(idx, label_namespace="idxs_tags", skip_indexing=True) - return Instance(d) - - split = list(split) - if len(split) < 5: - split.append(itertools.count()) - instances = map(_make_instance, *split) - return instances - - def get_metrics(self, reset=False): - """Get metrics specific to the task""" - acc = self.scorer1.get_metric(reset) - return {"accuracy": acc} - - -@register_task("swag", rel_path="SWAG/") -class SWAGTask(MultipleChoiceTask): - """ Task class for Situations with Adversarial Generations. """ - - def __init__(self, path, max_seq_len, name, **kw): - super().__init__(name, **kw) - self.path = path - self.max_seq_len = max_seq_len - - self.train_data_text = None - self.val_data_text = None - self.test_data_text = None - - self.scorer1 = CategoricalAccuracy() - self.scorers = [self.scorer1] - self.val_metric = "%s_accuracy" % name - self.val_metric_decreases = False - self.n_choices = 4 - - def load_data(self): - """ Process the dataset located at path. """ - - def _load_split(data_file): - questions, choicess, targs = [], [], [] - data = pd.read_csv(data_file) - for ex_idx, ex in data.iterrows(): - sent1 = tokenize_and_truncate(self._tokenizer_name, ex["sent1"], self.max_seq_len) - questions.append(sent1) - sent2_prefix = ex["sent2"] - choices = [] - for i in range(4): - choice = sent2_prefix + " " + ex["ending%d" % i] - choice = tokenize_and_truncate(self._tokenizer_name, choice, self.max_seq_len) - choices.append(choice) - choicess.append(choices) - targ = ex["label"] if "label" in ex else 0 - targs.append(targ) - return [questions, choicess, targs] - - self.train_data_text = _load_split(os.path.join(self.path, "train.csv")) - self.val_data_text = _load_split(os.path.join(self.path, "val.csv")) - self.test_data_text = _load_split(os.path.join(self.path, "test.csv")) - self.sentences = ( - self.train_data_text[0] - + self.val_data_text[0] - + [choice for choices in self.train_data_text[1] for choice in choices] - + [choice for choices in self.val_data_text[1] for choice in choices] - ) - log.info("\tFinished loading SWAG data.") - - def process_split( - self, split, indexers, model_preprocessing_interface - ) -> Iterable[Type[Instance]]: - """ Process split text into a list of AllenNLP Instances. """ - - def _make_instance(question, choices, label, idx): - d = {} - d["question_str"] = MetadataField(" ".join(question)) - if not model_preprocessing_interface.model_flags["uses_pair_embedding"]: - d["question"] = sentence_to_text_field( - model_preprocessing_interface.boundary_token_fn(question), indexers - ) - for choice_idx, choice in enumerate(choices): - inp = ( - model_preprocessing_interface.boundary_token_fn(question, choice) - if model_preprocessing_interface.model_flags["uses_pair_embedding"] - else model_preprocessing_interface.boundary_token_fn(choice) - ) - d["choice%d" % choice_idx] = sentence_to_text_field(inp, indexers) - d["choice%d_str" % choice_idx] = MetadataField(" ".join(choice)) - d["label"] = LabelField(label, label_namespace="labels", skip_indexing=True) - d["idx"] = LabelField(idx, label_namespace="idxs_tags", skip_indexing=True) - return Instance(d) - - split = list(split) - if len(split) < 4: - split.append(itertools.count()) - instances = map(_make_instance, *split) - return instances - - def get_metrics(self, reset=False): - """Get metrics specific to the task""" - acc = self.scorer1.get_metric(reset) - return {"accuracy": acc} - - -@register_task("hellaswag", rel_path="HellaSwag/") -class HellaSwagTask(MultipleChoiceTask): - """ Task class for HellaSwag. """ - - def __init__(self, path, max_seq_len, name, **kw): - super().__init__(name, **kw) - self.path = path - self.max_seq_len = max_seq_len - - self.train_data_text = None - self.val_data_text = None - self.test_data_text = None - - self.scorer1 = CategoricalAccuracy() - self.scorers = [self.scorer1] - self.val_metric = "%s_accuracy" % name - self.val_metric_decreases = False - self.n_choices = 4 - - def load_data(self): - """ Process the dataset located at path. """ - - def _load_split(data_file): - questions, choicess, targs, idxs = [], [], [], [] - data = [json.loads(l) for l in open(data_file, encoding="utf-8")] - for example in data: - sent1 = tokenize_and_truncate( - self._tokenizer_name, example["ctx_a"], self.max_seq_len - ) - questions.append(sent1) - sent2_prefix = example["ctx_b"] - choices = [ - tokenize_and_truncate( - self._tokenizer_name, sent2_prefix + " " + ending, self.max_seq_len - ) - for ending in example["endings"] - ] - choicess.append(choices) - targ = example["label"] if "label" in example else 0 - idx = example["ind"] - targs.append(targ) - idxs.append(idx) - return [questions, choicess, targs, idxs] - - self.train_data_text = _load_split(os.path.join(self.path, "hellaswag_train.jsonl")) - self.val_data_text = _load_split(os.path.join(self.path, "hellaswag_val.jsonl")) - self.test_data_text = _load_split(os.path.join(self.path, "hellaswag_test.jsonl")) - self.sentences = ( - self.train_data_text[0] - + self.val_data_text[0] - + [choice for choices in self.train_data_text[1] for choice in choices] - + [choice for choices in self.val_data_text[1] for choice in choices] - ) - log.info("\tFinished loading HellaSwag data.") - - def process_split( - self, split, indexers, model_preprocessing_interface - ) -> Iterable[Type[Instance]]: - """ Process split text into a list of AllenNLP Instances. """ - - def _make_instance(question, choices, label, idx): - d = {} - d["question_str"] = MetadataField(" ".join(question)) - if not model_preprocessing_interface.model_flags["uses_pair_embedding"]: - d["question"] = sentence_to_text_field( - model_preprocessing_interface.boundary_token_fn(question), indexers - ) - for choice_idx, choice in enumerate(choices): - inp = ( - model_preprocessing_interface.boundary_token_fn(question, choice) - if model_preprocessing_interface.model_flags["uses_pair_embedding"] - else model_preprocessing_interface.boundary_token_fn(choice) - ) - d["choice%d" % choice_idx] = sentence_to_text_field(inp, indexers) - d["choice%d_str" % choice_idx] = MetadataField(" ".join(choice)) - d["label"] = LabelField(label, label_namespace="labels", skip_indexing=True) - d["idx"] = LabelField(idx, label_namespace="idxs_tags", skip_indexing=True) - return Instance(d) - - split = list(split) - instances = map(_make_instance, *split) - return instances - - def get_metrics(self, reset=False): - """Get metrics specific to the task""" - acc = self.scorer1.get_metric(reset) - return {"accuracy": acc} - - -@register_task("winograd-coreference", rel_path="WSC") -class WinogradCoreferenceTask(SpanClassificationTask): - def __init__(self, path, **kw): - self._files_by_split = {"train": "train.jsonl", "val": "val.jsonl", "test": "test.jsonl"} - self.num_spans = 2 - super().__init__( - files_by_split=self._files_by_split, label_file="labels.txt", path=path, **kw - ) - self.n_classes = 2 - self.val_metric = "%s_acc" % self.name - - def load_data(self): - iters_by_split = collections.OrderedDict() - for split, filename in self._files_by_split.items(): - if filename.endswith("test.jsonl"): - iters_by_split[split] = load_span_data( - self.tokenizer_name, filename, has_labels=False - ) - else: - iters_by_split[split] = load_span_data( - self.tokenizer_name, filename, label_fn=lambda x: int(x) - ) - self._iters_by_split = iters_by_split - - def update_metrics(self, out, batch): - logits = out["logits"] - labels = batch["labels"] - logits, labels = logits.detach(), labels.detach() - _, preds = logits.max(dim=1) - - self.f1_scorer(logits, labels) # expects [batch_size, n_classes] for preds - self.acc_scorer(preds, labels) # expects [batch_size, 1] for both - - def get_metrics(self, reset=False): - """Get metrics specific to the task""" - collected_metrics = { - "f1": self.f1_scorer.get_metric(reset)[2], - "acc": self.acc_scorer.get_metric(reset), - } - return collected_metrics - - -@register_task("boolq", rel_path="BoolQ") -class BooleanQuestionTask(PairClassificationTask): - """Task class for Boolean Questions Task.""" - - def __init__(self, path, max_seq_len, name, **kw): - super().__init__(name, n_classes=2, **kw) - self.path = path - self.max_seq_len = max_seq_len - - self.train_data_text = None - self.val_data_text = None - self.test_data_text = None - - self.scorer2 = F1Measure(1) - self.scorers = [self.scorer1, self.scorer2] - self.val_metric = "%s_acc_f1" % name - self.val_metric_decreases = False - - def load_data(self): - """ Process the dataset located at path. """ - - def _load_jsonl(data_file): - raw_data = [json.loads(d) for d in open(data_file, encoding="utf-8")] - data = [] - for d in raw_data: - question = tokenize_and_truncate( - self._tokenizer_name, d["question"], self.max_seq_len - ) - passage = tokenize_and_truncate( - self._tokenizer_name, d["passage"], self.max_seq_len - ) - new_datum = {"question": question, "passage": passage} - answer = d["label"] if "label" in d else False - new_datum["label"] = answer - data.append(new_datum) - return data - - self.train_data_text = _load_jsonl(os.path.join(self.path, "train.jsonl")) - self.val_data_text = _load_jsonl(os.path.join(self.path, "val.jsonl")) - self.test_data_text = _load_jsonl(os.path.join(self.path, "test.jsonl")) - - self.sentences = [d["question"] for d in self.train_data_text + self.val_data_text] + [ - d["passage"] for d in self.train_data_text + self.val_data_text - ] - log.info("\tFinished loading BoolQ data.") - - def process_split( - self, split, indexers, model_preprocessing_interface - ) -> Iterable[Type[Instance]]: - """ Process split text into a list of AllenNLP Instances. """ - - def _make_instance(d, idx): - new_d = {} - new_d["question_str"] = MetadataField(" ".join(d["question"])) - new_d["passage_str"] = MetadataField(" ".join(d["passage"])) - if not model_preprocessing_interface.model_flags["uses_pair_embedding"]: - new_d["input1"] = sentence_to_text_field( - model_preprocessing_interface.boundary_token_fn(d["passage"]), indexers - ) - new_d["input2"] = sentence_to_text_field( - model_preprocessing_interface.boundary_token_fn(d["question"]), indexers - ) - else: # BERT/XLNet - psg_qst = model_preprocessing_interface.boundary_token_fn( - d["passage"], d["question"] - ) - new_d["inputs"] = sentence_to_text_field(psg_qst, indexers) - new_d["labels"] = LabelField(d["label"], label_namespace="labels", skip_indexing=True) - new_d["idx"] = LabelField(idx, label_namespace="idxs_tags", skip_indexing=True) - return Instance(new_d) - - split = [split, itertools.count()] - instances = map(_make_instance, *split) - return instances - - def get_metrics(self, reset=False): - """Get metrics specific to the task""" - acc = self.scorer1.get_metric(reset) - pcs, rcl, f1 = self.scorer2.get_metric(reset) - return { - "acc_f1": (acc + f1) / 2, - "accuracy": acc, - "f1": f1, - "precision": pcs, - "recall": rcl, - } - - def count_examples(self, splits=["train", "val", "test"]): - """ Count examples in the dataset. """ - self.example_counts = {} - for split in splits: - st = self.get_split_text(split) - self.example_counts[split] = len(st) - - -@register_task("anli", rel_path="aNLI") -class AlphaNLITask(MultipleChoiceTask): - """ - Task class for Abductive Natural Language Inference. - - Paper: https://arxiv.org/abs/1908.05739 - Website: https://leaderboard.allenai.org/anli/submissions/get-started - """ - - def __init__(self, path, max_seq_len, name, **kw): - super().__init__(name, **kw) - self.path = path - self.max_seq_len = max_seq_len - - self.train_data_text = None - self.val_data_text = None - self.test_data_text = None - - self.scorer1 = CategoricalAccuracy() - self.scorers = [self.scorer1] - self.val_metric = "%s_accuracy" % name - self.val_metric_decreases = False - self.n_choices = 2 - - def load_data(self): - """ Process the dataset located at path. """ - - def _load_split(inputs_file, labels_file): - obs1, hyp1, hyp2, obs2 = [], [], [], [] - with open(inputs_file, encoding="utf-8") as f: - for line in f: - row = json.loads(line) - obs1.append( - tokenize_and_truncate(self._tokenizer_name, row["obs1"], self.max_seq_len) - ) - hyp1.append( - tokenize_and_truncate(self._tokenizer_name, row["hyp1"], self.max_seq_len) - ) - hyp2.append( - tokenize_and_truncate(self._tokenizer_name, row["hyp2"], self.max_seq_len) - ) - obs2.append( - tokenize_and_truncate(self._tokenizer_name, row["obs2"], self.max_seq_len) - ) - with open(labels_file) as f: - labels = [int(i) - 1 for i in f.read().split()] # -1 to get {0, 1} labels - return [obs1, hyp1, hyp2, obs2, labels] - - self.train_data_text = _load_split( - inputs_file=os.path.join(self.path, "train.jsonl"), - labels_file=os.path.join(self.path, "train-labels.lst"), - ) - self.val_data_text = _load_split( - inputs_file=os.path.join(self.path, "dev.jsonl"), - labels_file=os.path.join(self.path, "dev-labels.lst"), - ) - - log.warning("aNLI has no public test set, so we reuse the dev set as a stand-in") - self.test_data_text = self.val_data_text - self.sentences = ( - self.train_data_text[0] - + self.train_data_text[1] - + self.train_data_text[2] - + self.train_data_text[3] - + self.val_data_text[0] - + self.val_data_text[1] - + self.val_data_text[2] - + self.val_data_text[3] - ) - log.info("\tFinished loading aNLI data.") - - def process_split( - self, split, indexers, model_preprocessing_interface - ) -> Iterable[Type[Instance]]: - """ Process split text into a list of AllenNLP Instances. """ - - def _make_instance(obs1, hyp1, hyp2, obs2, label, idx): - d = {} - if not model_preprocessing_interface.model_flags["uses_pair_embedding"]: - # We're combining obs1 and obs2 in a potentially suboptimal way here - d["question"] = sentence_to_text_field( - model_preprocessing_interface.boundary_token_fn(obs1 + obs2), indexers - ) - d["question_str"] = MetadataField(" ".join(obs1 + obs2)) - for hyp_idx, hyp in enumerate([hyp1, hyp2]): - d["choice%d" % hyp_idx] = sentence_to_text_field( - model_preprocessing_interface.boundary_token_fn(hyp), indexers - ) - d["choice%d_str" % hyp_idx] = MetadataField(" ".join(hyp)) - else: - for hyp_idx, hyp in enumerate([hyp1, hyp2]): - inp = ( - model_preprocessing_interface.boundary_token_fn(obs1 + hyp, obs2) - if model_preprocessing_interface.model_flags["uses_pair_embedding"] - else model_preprocessing_interface.boundary_token_fn(hyp) - ) - d["choice%d" % hyp_idx] = sentence_to_text_field(inp, indexers) - d["choice%d_str" % hyp_idx] = MetadataField(" ".join(inp)) - d["label"] = LabelField(label, label_namespace="labels", skip_indexing=True) - d["idx"] = LabelField(idx, label_namespace="idxs_tags", skip_indexing=True) - return Instance(d) - - split = list(split) - if len(split) < 6: - split.append(itertools.count()) - instances = map(_make_instance, *split) - return instances - - def get_metrics(self, reset=False): - """Get metrics specific to the task""" - acc = self.scorer1.get_metric(reset) - return {"accuracy": acc} - - -@register_task("scitail", rel_path="SciTailV1.1/tsv_format/") -class SciTailTask(PairClassificationTask): - """ Task class for SciTail http://data.allenai.org/scitail/ """ - - def __init__(self, path, max_seq_len, name, **kw): - super().__init__(name, n_classes=2, **kw) - self.path = path - self.max_seq_len = max_seq_len - - self.train_data_text = None - self.val_data_text = None - self.test_data_text = None - - def load_data(self): - """Process and load Scitail data""" - targ_map = {"neutral": 0, "entails": 1} - self.train_data_text = load_tsv( - self._tokenizer_name, - os.path.join(self.path, "scitail_1.0_train.tsv"), - max_seq_len=self.max_seq_len, - label_fn=targ_map.__getitem__, - ) - self.val_data_text = load_tsv( - self._tokenizer_name, - os.path.join(self.path, "scitail_1.0_dev.tsv"), - max_seq_len=self.max_seq_len, - label_fn=targ_map.__getitem__, - ) - self.test_data_text = load_tsv( - self._tokenizer_name, - os.path.join(self.path, "scitail_1.0_test.tsv"), - max_seq_len=self.max_seq_len, - label_fn=targ_map.__getitem__, - return_indices=True, - ) - self.sentences = ( - self.train_data_text[0] - + self.train_data_text[1] - + self.val_data_text[0] - + self.val_data_text[1] - ) - log.info("\tFinished loading SciTail") - - -@register_task("winogrande", rel_path="Winogrande/", train_size="xl") -# For experiment record management convenience, we use winogrande as an alias of winogrande-xl -@register_task("winogrande-xl", rel_path="Winogrande/", train_size="xl") -@register_task("winogrande-l", rel_path="Winogrande/", train_size="l") -@register_task("winogrande-m", rel_path="Winogrande/", train_size="m") -@register_task("winogrande-s", rel_path="Winogrande/", train_size="s") -@register_task("winogrande-xs", rel_path="Winogrande/", train_size="xs") -class WinograndeTask(MultipleChoiceTask): - def __init__(self, path, max_seq_len, name, train_size, **kw): - """ - Task class for Winogrande dataset. - - Paper: https://arxiv.org/abs/1907.10641 - Website (data download): https://mosaic.allenai.org/projects/winogrande - Reference code: https://github.com/allenai/winogrande - """ - super().__init__(name, **kw) - self.path = path - self.max_seq_len = max_seq_len - self.train_size = train_size - self.n_choices = 2 - - self.train_data_text = None - self.val_data_text = None - self.test_data_text = None - - self.scorer1 = CategoricalAccuracy() - self.scorers = [self.scorer1] - self.val_metric = "%s_accuracy" % name - self.val_metric_decreases = False - - def load_data(self): - def _load_data(data_file): - data = [json.loads(l) for l in open(data_file, encoding="utf-8").readlines()] - contexts, choices, labels, idxs = [], [], [], [] - for i, example in enumerate(data): - sent_part1, sent_part2 = example["sentence"].split("_") - sent_part1_tokens = tokenize_and_truncate( - self._tokenizer_name, sent_part1, self.max_seq_len - ) - choice_tokens = [ - tokenize_and_truncate( - self._tokenizer_name, example["option1"] + sent_part2, self.max_seq_len - ), - tokenize_and_truncate( - self._tokenizer_name, example["option2"] + sent_part2, self.max_seq_len - ), - ] - contexts.append(sent_part1_tokens) - choices.append(choice_tokens) - labels.append(int(example["answer"] if "answer" in example else "1") - 1) - idxs.append(example["qID"]) - return [contexts, choices, labels, idxs] - - self.train_data_text = _load_data( - os.path.join(self.path, "train_%s.jsonl" % self.train_size) - ) - self.val_data_text = _load_data(os.path.join(self.path, "dev.jsonl")) - self.test_data_text = _load_data(os.path.join(self.path, "test.jsonl")) - self.sentences = ( - self.train_data_text[0] - + self.val_data_text[0] - + self.train_data_text[1][0] - + self.train_data_text[1][1] - + self.val_data_text[1][0] - + self.val_data_text[1][1] - ) - - log.info("\tFinished loading Winogrande data.") - - def process_split( - self, split, indexers, model_preprocessing_interface - ) -> Iterable[Type[Instance]]: - """ Process split text into a list of AllenNLP Instances. """ - - def _make_instance(context, choices, label, idx): - # because Winogrande uses MultiTaskModel._mc_forward as its forward funcion, we adapt - # to the keywords specified in _mc_forward, i.e. "question", "choice1" and "choice2". - d = {} - d["question_str"] = MetadataField(" ".join(context)) - if not model_preprocessing_interface.model_flags["uses_pair_embedding"]: - d["question"] = sentence_to_text_field( - model_preprocessing_interface.boundary_token_fn(context), indexers - ) - for choice_idx, choice in enumerate(choices): - inp = ( - model_preprocessing_interface.boundary_token_fn(context, choice) - if model_preprocessing_interface.model_flags["uses_pair_embedding"] - else model_preprocessing_interface.boundary_token_fn(choice) - ) - d["choice%d" % choice_idx] = sentence_to_text_field(inp, indexers) - d["choice%d_str" % choice_idx] = MetadataField(" ".join(choice)) - d["label"] = LabelField(label, label_namespace="labels", skip_indexing=True) - d["idx"] = MetadataField(idx) - return Instance(d) - - split = list(split) - instances = map(_make_instance, *split) - return instances - - def get_metrics(self, reset=False): - """Get metrics specific to the task""" - acc = self.scorer1.get_metric(reset) - return {"accuracy": acc} - - -@register_task("wikipedia_corpus_sop", rel_path="wikipedia_sop_small") -class SentenceOrderTask(PairClassificationTask): - """ Task class for Sentence Order Prediction (SOP). See the ALBERT paper for details on SOP: - https://arxiv.org/abs/1909.11942. - We are currently using an preprocessed version of the Wikipedia corpus - (more specifically, the Wikidump version 2020-03-01 data) that consists of 5% of the data. You can generate - the data by following the instructions from jiant/scripts/sop. - One thing to note about our SOP ALBERT implementation is that we do not load the pretrained - weights for the SOP head because they are unavailable in Huggingface. We only use the - pretrained weights of the linear layer from ALBERT that creates the pooled output used in SOP. - """ - - def __init__(self, path, max_seq_len, name, **kw): - super(SentenceOrderTask, self).__init__(name, n_classes=2, **kw) - self.path = path - self.max_seq_len = max_seq_len - self.train_data_text = None - self.val_data_text = None - self.test_data_text = None - self.files_by_split = { - "train": os.path.join(path, "train.txt"), - "val": os.path.join(path, "valid.txt"), - "test": os.path.join(path, "test.txt"), - } - self._label_namespace = self.name + "_labels" - - def get_target_seq_length(self): - target_is_max = random.random() > 0.1 - max_seq_len = self.max_seq_len - 3 # exclude [CLS], [SEP], and [SEP] - if target_is_max: - target_seq_length = max_seq_len - else: - target_seq_length = random.randint(2, max_seq_len) - return target_seq_length - - def get_data_iter(self, path): - """Loading data file and tokenizing the text. We override the - this function and all functions that call this function because - the step of reading in the data for SOP is different than other - PairClassificationTasks. - - ALBERT does SOP classification by, for each document: - For each example, we first fetch as many sentences as possible that cumulatively have - target_seq_length number of tokens from the document: - -90% of the time, this target_seq_length is equal to max_seq_length, and - 10% of the time, it is set to a random number of tokens between 2 and max_seq_length. - -Given the sampled sentences, randomly sample N such that the first N sentences in the - sampled go to the first segment, and the rest go to the second. - -50% of the time, the first and second segments are switched. - - Args: - path: (str) data file path - """ - - def _tokenize(tokenizer_name, sent): - tokenizer = get_tokenizer(tokenizer_name) - return tokenizer.tokenize(sent) - - def is_end_document(seg): - tokenized_eod = _tokenize(self._tokenizer_name, "END OF ARTICLE") - return set(tokenized_eod).issubset(set(seg)) - - # The code below is adapted from the original ALBERT code. See: - # https://github.com/google-research/albert/blob/master/create_pretraining_data.py#L267. - f = open(path, "r") - # The dataset comes with one sentence per line, thus we split by - # line here. - current_chunk = [_tokenize(self._tokenizer_name, next(f))] - current_length = len(current_chunk[0]) - target_seq_length = self.get_target_seq_length() - while len(current_chunk) > 0: - segment = next(f) - segment = _tokenize(self._tokenizer_name, segment) - if is_end_document(segment) or current_length >= target_seq_length: - for_next_chunk = [] - if current_length > target_seq_length: - # Since the most current sentence added to the chunk exceeds the target - # length, we save it for the next chunk (next example). - for_next_chunk.append(current_chunk.pop()) - if not is_end_document(segment): - for_next_chunk.append(segment) - target_seq_length = self.get_target_seq_length() - if len(current_chunk) >= 2: - # Make sure we have at least 2 sentences to distribute between the two - # segments. - a_end = random.randint(1, len(current_chunk) - 1) - tokens_a = [] - for j in range(a_end): - tokens_a.extend(current_chunk[j]) - tokens_b = [] - for j in range(a_end, len(current_chunk)): - tokens_b.extend(current_chunk[j]) - in_order = random.random() < 0.5 - if in_order: - yield (tokens_a, tokens_b, in_order) - else: - yield (tokens_b, tokens_a, in_order) - # if len(current_chunk) >=2, we will yield and reinitialize - # if len(current_chunk) ==1, we will not yeild, and reinitialize - if len(for_next_chunk) > 0 and not is_end_document(segment): - # Make sure we only sample articles for each example that - # belong to the same document. - current_chunk = for_next_chunk - current_length = sum([len(chunk) for chunk in for_next_chunk]) - else: - # We find the next sentence for the next example. - try: # Might run into StopIterationError - current_chunk = [_tokenize(self._tokenizer_name, next(f))] - current_length = len(current_chunk[0]) - except: - print("Done loading data for SOP") - current_chunk = [] - current_length = 0 - pass - else: - current_chunk.append(segment) - current_length += len(segment) - - def load_data(self): - pass - - def process_split( - self, split, indexers, model_preprocessing_interface - ) -> Iterable[Type[Instance]]: - """Process a sentence order prediction split by indexing and creating fields. - We override the PairClassificationTask process_split because our data split - is different from the typical PairClassificationTask due to the more memory-efficient - generator way of loading data we employ for SOP due to the dataset size. - Args: - split: (list) a single list of sentences - indexers: (Indexer object) indexer to index input words - """ - - def _make_instance(sent_pairs_): - sent_a, sent_b, is_right_order = sent_pairs_ - inp = model_preprocessing_interface.boundary_token_fn(sent_a, sent_b) - input_sent = sentence_to_text_field(inp, indexers) - label = LabelField(is_right_order, label_namespace="labels", skip_indexing=True) - d = {"inputs": input_sent, "labels": label} - return Instance(d) - - for sent_pairs in split: - yield _make_instance(sent_pairs) - - def get_split_text(self, split: str): - """Get split text as iterable of records. - Args: - split: (str) should be one of 'train', 'val', or 'test'. - """ - return self.get_data_iter(self.files_by_split[split]) - - def get_sentences(self) -> Iterable[Sequence[str]]: - """Yield sentences, used to compute vocabulary. - """ - for split in self.files_by_split: - # Don't use test set for vocab building. - if split.startswith("test"): - continue - for sent in self.get_data_iter(self.files_by_split[split]): - # only counting sent[0] is enough for computing vocab - yield sent[0] - - def count_examples(self): - """Computes number of samples - Assuming every line is one example. - """ - example_counts = {} - for split, split_path in self.files_by_split.items(): - example_counts[split] = sum(1 for _ in self.get_data_iter(split_path)) - self.example_counts = example_counts diff --git a/jiant/tasks/utils.py b/jiant/tasks/utils.py new file mode 100644 index 000000000..78caba323 --- /dev/null +++ b/jiant/tasks/utils.py @@ -0,0 +1,93 @@ +import numpy as np + +from typing import NamedTuple, Sequence + + +class InclusiveSpan(NamedTuple): + start: int + end: int + + def to_slice(self): + return slice(self.start, self.end + 1) + + def to_inclusive(self): + return self + + def to_exclusive(self): + return ExclusiveSpan(start=self.start, end=self.end + 1) + + +class ExclusiveSpan(NamedTuple): + start: int + end: int + + def to_slice(self): + return slice(self.start, self.end) + + def to_inclusive(self): + return ExclusiveSpan(start=self.start, end=self.end - 1) + + def to_exclusive(self): + return self + + +def truncate_sequences(tokens_ls: Sequence[Sequence], max_length: int, truncate_end: bool = True): + """Takes a sequence of sequences and trims the sub-seqs to fit within the max length. + + Trims the length of subsequences within a sequence until the total length of the combined sub- + sequences is within the max_length. While total length exceeds the max_length, trims whichever + subsequence is longest until the total combined length of the subsequences is under the limit. + + Args: + tokens_ls (Sequence[Sequence]): sequence of subsequences to truncate. + max_length (int): the maximum length of the combined sub-sequences. + truncate_end (bool): if True, truncate from the end of the sub-sequence, else from start. + + Returns: + Sequence[Sequence] with subsequences trimmed to fit within the max length when combined. + + """ + if len(tokens_ls) == 0: + return [] + if len(tokens_ls) == 1: + if truncate_end: + return [tokens_ls[0][:max_length]] + else: + return [tokens_ls[0][-max_length:]] + lengths = np.array([len(tokens) for tokens in tokens_ls]) + total_length = lengths.sum() + if total_length < max_length: + return tokens_ls + target_lengths = lengths + while sum(target_lengths) > max_length: + target_lengths[np.argmax(target_lengths)] -= 1 + + return [ + tokens[:target_length] if truncate_end else tokens[-target_length:] + for tokens, target_length in zip(tokens_ls, target_lengths) + ] + + +def pad_to_max_seq_length(ls, max_seq_length, pad_idx=0, pad_right=True, check=True): + """Apply padding to an input sequence. + + Args: + ls: sequence to pad. + max_seq_length: max length up to which to apply padding. + pad_idx: element to use for padding. + pad_right: True if padding is applied to right side of sequence, False to pad on left side. + check: True if result length should be checked as under the max sequence length. + + Returns: + Sequence with specified padding applied. + + """ + padding = [pad_idx] * (max_seq_length - len(ls)) + if pad_right: + result = ls + padding + else: + result = padding + ls + + if check: + assert len(result) == max_seq_length + return result diff --git a/jiant/trainer.py b/jiant/trainer.py deleted file mode 100644 index c50ff7f7d..000000000 --- a/jiant/trainer.py +++ /dev/null @@ -1,1319 +0,0 @@ -""" Trainer """ -import copy -import glob -import itertools -import logging as log -import math -import os -import random -import re -import time - -import numpy as np -import torch -from allennlp.common import Params # pylint: disable=import-error -from allennlp.common.checks import ConfigurationError # pylint: disable=import-error -from allennlp.data.iterators import BasicIterator, BucketIterator # pylint: disable=import-error -from allennlp.training.learning_rate_schedulers import ( # pylint: disable=import-error - LearningRateScheduler, -) -from allennlp.nn.util import device_mapping -from allennlp.training.optimizers import Optimizer # pylint: disable=import-error -from tensorboardX import SummaryWriter # pylint: disable=import-error -from torch.nn.utils.clip_grad import clip_grad_norm_ -from torch.optim.lr_scheduler import ReduceLROnPlateau - -from jiant.evaluate import evaluate -from jiant.tasks.seq2seq import Seq2SeqTask -from jiant.utils import config -from jiant.utils.utils import ( - assert_for_log, - find_last_checkpoint_epoch, - check_for_previous_checkpoints, - get_output_attribute, - get_model_attribute, - uses_cuda, -) # pylint: disable=import-error -from allennlp.nn.util import move_to_device - - -def build_trainer_params(args, cuda_device, task_names, phase="pretrain"): - """ Helper function which extracts trainer parameters from args. - In particular, we want to search args for task specific training parameters. - """ - - def _get_attr(attr_name, default=None): - if phase == "pretrain": - # We ignore task-specific trainer attributes during pretraining. - if default is not None: - return default - return args[attr_name] - else: - # During target task training, we get task-specific attributes if available. - assert len(task_names) == 1 - return config.get_task_attr(args, task_names[0], attr_name, default) - - params = {} - train_opts = [ - "optimizer", - "lr", - "batch_size", - "lr_decay_factor", - "lr_patience", - "patience", - "scheduler_threshold", - "sent_enc", - "d_hid", - "max_grad_norm", - "min_lr", - "cuda", - "keep_all_checkpoints", - "val_data_limit", - "max_epochs", - "dec_val_scale", - "accumulation_steps", - ] - for attr in train_opts: - params[attr] = _get_attr(attr) - - # Special case: If no task-specific arg is found for these, we'll need to fall back to a - # phase-specific default. - params["max_vals"] = _get_attr( - "max_vals", default=args.target_train_max_vals if phase == "target_train" else None - ) - params["val_interval"] = _get_attr( - "val_interval", default=args.target_train_val_interval if phase == "target_train" else None - ) - params["training_data_fraction"] = _get_attr( - "training_data_fraction", - default=args.target_train_data_fraction - if phase == "target_train" - else args.pretrain_data_fraction, - ) - params["cuda"] = cuda_device - return Params(params) - - -def build_trainer( - args, - cuda_device, - task_names, - model, - run_dir, - metric_should_decrease=True, - train_type="SamplingMultiTaskTrainer", - phase="pretrain", -): - """Build a trainer from params. - - Parameters - ---------- - params: Trainer parameters as built by build_trainer_params. - model: A module with trainable parameters. - run_dir: The directory where we save the models. - - Returns - ------- - A trainer object, a trainer config object, an optimizer config object, - and a scheduler config object. - """ - params = build_trainer_params(args, cuda_device, task_names, phase) - - opt_params = {"type": params["optimizer"], "lr": params["lr"]} - if params["optimizer"] == "adam": - # AMSGrad is a flag variant of Adam, not its own object. - opt_params["amsgrad"] = True - elif params["optimizer"] == "bert_adam": - # Transformer scheduler uses number of opt steps, if known in advance, to set the LR. - # We leave it as -1 here (unknown) and set it if known later. - opt_params["t_total"] = -1 - opt_params["warmup"] = 0.1 - opt_params = Params(opt_params) - - schd_params = Params( - { - "type": "reduce_on_plateau", - "mode": "min" if metric_should_decrease else "max", - "factor": params["lr_decay_factor"], - "patience": params["lr_patience"], - "threshold": params["scheduler_threshold"], - "threshold_mode": "abs", - "verbose": True, - } - ) - - train_params = Params( - { - "cuda_device": params["cuda"], - "patience": params["patience"], - "grad_norm": params["max_grad_norm"], - "val_interval": params["val_interval"], - "max_vals": params["max_vals"], - "lr_decay": 0.99, - "min_lr": params["min_lr"], - "keep_all_checkpoints": params["keep_all_checkpoints"], - "val_data_limit": params["val_data_limit"], - "max_epochs": params["max_epochs"], - "dec_val_scale": params["dec_val_scale"], - "training_data_fraction": params["training_data_fraction"], - "accumulation_steps": params["accumulation_steps"], - } - ) - assert ( - train_type == "SamplingMultiTaskTrainer" - ), "We currently only support SamplingMultiTaskTrainer" - - if train_type == "SamplingMultiTaskTrainer": - trainer = SamplingMultiTaskTrainer.from_params(model, run_dir, copy.deepcopy(train_params)) - return trainer, train_params, opt_params, schd_params - - -class SamplingMultiTaskTrainer: - def __init__( - self, - model, - patience=2, - val_interval=100, - max_vals=50, - serialization_dir=None, - cuda_device=-1, - grad_norm=None, - grad_clipping=None, - lr_decay=None, - min_lr=None, - keep_all_checkpoints=False, - val_data_limit=5000, - max_epochs=-1, - dec_val_scale=100, - training_data_fraction=1.0, - accumulation_steps=1, - ): - """ - The training coordinator. Unusually complicated to handle MTL with tasks of - diverse sizes. - - Parameters - ---------- - model : ``Model``, required. - An AllenNLP model to be optimized. Pytorch Modules can also be optimized if - their ``forward`` method returns a dictionary with a "loss" key, containing a - scalar tensor representing the loss function to be optimized. - patience , optional (default=2) - Number of validations to be patient before early stopping. - val_metric , optional (default="loss") - Validation metric to measure for whether to stop training using patience - and whether to serialize an ``is_best`` model after each validation. The metric name - must be prepended with either "+" or "-", which specifies whether the metric - is an increasing or decreasing function. - serialization_dir , optional (default=None) - Path to directory for saving and loading model files. Models will not be saved if - this parameter is not passed. - cuda_device , optional (default = -1) - An integer specifying the CUDA device to use. If -1, the CPU is used. - Multi-gpu training is not currently supported, but will be once the - Pytorch DataParallel API stabilises. - grad_norm : float, optional, (default = None). - If provided, gradient norms will be rescaled to have a maximum of this value. - grad_clipping : ``float``, optional (default = ``None``). - If provided, gradients will be clipped `during the backward pass` to have an (absolute) - maximum of this value. If you are getting ``NaNs`` in your gradients during training - that are not solved by using ``grad_norm``, you may need this. - keep_all_checkpoints : If set, keep checkpoints from every validation. Otherwise, keep only - best and (if different) most recent. - val_data_limit: During training, use only the first N examples from the validation set. - Set to -1 to use all. - training_data_fraction: If set to a float between 0 and 1, load only the specified - percentage of examples. Hashing is used to ensure that the same examples are loaded - each epoch. - """ - self._model = model - - self._patience = patience - self._max_vals = max_vals - self._val_interval = val_interval - self._serialization_dir = serialization_dir - self._cuda_device = cuda_device - self._grad_norm = grad_norm - self._grad_clipping = grad_clipping - self._lr_decay = lr_decay - self._min_lr = min_lr - self._keep_all_checkpoints = keep_all_checkpoints - self._val_data_limit = val_data_limit - self._max_epochs = max_epochs - self._dec_val_scale = dec_val_scale - self._training_data_fraction = training_data_fraction - self._task_infos = None - self._metric_infos = None - self._scheduler = None - self._optimizer = None - self._accumulation_steps = accumulation_steps - - self._log_interval = 10 # seconds - - self._TB_dir = None - if self._serialization_dir is not None: - self._TB_dir = os.path.join(self._serialization_dir, "tensorboard") - self._TB_train_log = SummaryWriter(os.path.join(self._TB_dir, "train")) - self._TB_validation_log = SummaryWriter(os.path.join(self._TB_dir, "val")) - - def _check_history(self, metric_history, cur_score, should_decrease=False): - """ - Given a the history of the performance on a metric - and the current score, check if current score is - best so far and if out of patience. - """ - patience = self._patience + 1 - best_fn = min if should_decrease else max - best_score = best_fn(metric_history) - if best_score == cur_score: - best_so_far = metric_history.index(best_score) == len(metric_history) - 1 - else: - best_so_far = False - - if should_decrease: - index_of_last_improvement = metric_history.index(min(metric_history)) - out_of_patience = index_of_last_improvement <= len(metric_history) - (patience + 1) - else: - index_of_last_improvement = metric_history.index(max(metric_history)) - out_of_patience = index_of_last_improvement <= len(metric_history) - (patience + 1) - - return best_so_far, out_of_patience - - def _setup_training( - self, tasks, batch_size, train_params, optimizer_params, scheduler_params, phase - ): - """ Set up the trainer by initializing task_infos and metric_infos, which - track necessary information about the training status of each task and metric respectively. - - Returns: - - task_infos (Dict[str:Dict[str:???]]): dictionary containing where each task_info - contains: - - iterator: a task specific (because it uses that task's fields to dynamically - batch) batcher - - n_tr_batches: the number of training batches - - tr_generator: generator object that returns the batches, set to repeat - indefinitely - - loss: the accumulated loss (during training or validation) - - n_batches_since_val: number of batches trained on since the last validation - - total_batches_trained: number of batches trained over all validation checks - - optimizer: a task specific optimizer, not used if the global optimizer is not - None - - scheduler: a task specific scheduler, not used if the global optimizer is not - None - - stopped: a bool indicating if that task is stopped or not (if it ran out of - patience or hit min lr) - - last_log: the time we last logged progress for the task - - - metric_infos (Dict[str:Dict[str:???]]): dictionary containing metric information. - Each metric should be the validation metric of a task, except {micro/macro}_avg, - which are privileged to get an aggregate multi-task score. Each dict contains: - - hist (List[float]): previous values of the metric - - stopped (Bool): whether or not that metric is stopped or not - - best (Tuple(Int, Dict)): information on the best value of that metric and when - it happened - """ - task_infos = {task.name: {} for task in tasks} - for task in tasks: - task_info = task_infos[task.name] - if ( - os.path.exists(os.path.join(self._serialization_dir, task.name)) is False - and phase == "target_train" - ): - os.mkdir(os.path.join(self._serialization_dir, task.name)) - - instance = [ - i - for i in itertools.islice( - task.get_instance_iterable(split_name="train", phase=phase), 1 - ) - ][0] - pad_dict = instance.get_padding_lengths() - sorting_keys = [] - for field in pad_dict: - for pad_field in pad_dict[field]: - sorting_keys.append((field, pad_field)) - iterator = BucketIterator( - sorting_keys=sorting_keys, - max_instances_in_memory=10000, - batch_size=batch_size, - biggest_batch_first=True, - ) - task_info["iterator"] = iterator - task_info["tr_generator"] = iterator( - task.get_instance_iterable(split_name="train", phase=phase), num_epochs=None - ) - - n_training_examples = task.n_train_examples - # Warning: This won't be precise when training_data_fraction is set, since each - # example is included or excluded deterministically using a hashing function. - # See read_records function in serialize.py for details. - n_training_examples *= self._training_data_fraction - task_info["n_tr_batches"] = math.ceil(n_training_examples / batch_size) - task_info["n_tr_steps"] = math.ceil( - task_info["n_tr_batches"] / self._accumulation_steps - ) - - task_info["loss_since_val"] = 0.0 - task_info["total_batches_trained"] = 0 - task_info["n_batches_since_val"] = 0 - task_info["total_steps_trained"] = 0 - task_info["n_steps_since_val"] = 0 - - task_info["stopped"] = False - task_info["last_log"] = time.time() - - # Metric bookkeeping - all_metrics = [task.val_metric for task in tasks] + ["micro_avg", "macro_avg"] - metric_infos = { - metric: {"hist": [], "stopped": False, "best": (-1, {})} for metric in all_metrics - } - self.task_to_metric_mapping = {task.val_metric: task.name for task in tasks} - self._task_infos = task_infos - self._metric_infos = metric_infos - return task_infos, metric_infos - - def get_scaling_weights(self, scaling_method, num_tasks, task_names, task_n_train_examples): - """ - - Parameters - ---------------- - scaling_method : str, scaling method - num_tasks: int - task_names: list of str - task_n_train_examples: list of ints of number of examples per task - - Returns - ---------------- - scaling weights: list of ints, to scale loss - """ - if scaling_method == "uniform": - scaling_weights = [1.0] * num_tasks - elif scaling_method == "max_proportional": - scaling_weights = task_n_train_examples.astype(float) - elif scaling_method == "max_proportional_log": - scaling_weights = np.log(task_n_train_examples) - elif "max_power_" in scaling_method: - scaling_power = float(scaling_method.strip("max_power_")) - scaling_weights = task_n_train_examples ** scaling_power - elif scaling_method == "max_inverse_log": - scaling_weights = 1 / np.log(task_n_train_examples) - elif scaling_method == "max_inverse": - scaling_weights = 1 / task_n_train_examples - # Weighting losses based on best validation step for each task from a previous uniform run, - # normalized by the maximum validation step - # eg. 'max_epoch_9_18_1_11_18_2_14_16_1' - elif "max_epoch_" in scaling_method: - epochs = scaling_method.strip("max_epoch_").split("_") - assert len(epochs) == num_tasks, "Loss Scaling Error: epoch number not match." - scaling_weights = np.array(list(map(int, epochs))) - # normalized by max weight - if "max" in scaling_method: - scaling_weights = scaling_weights / np.max(scaling_weights) - - scaling_weights = dict(zip(task_names, scaling_weights)) - return scaling_weights - - def get_sampling_weights( - self, weighting_method, num_tasks, task_n_train_examples, task_n_train_batches - ): - """ - Parameters - ---------------- - weighting_method: str, weighting method - num_tasks: int - task_n_train_examples: list of ints of number of examples per task - task_n_train_batches: list of ints of number of batches per task - - Returns - ---------------- - sampling weights: list of ints, to sample tasks to train on - """ - if weighting_method == "uniform": - sample_weights = [1.0] * num_tasks - elif weighting_method == "proportional": - sample_weights = task_n_train_examples.astype(float) - elif weighting_method == "proportional_log_batch": - sample_weights = np.log(task_n_train_batches) - elif weighting_method == "proportional_log_example": - sample_weights = np.log(task_n_train_examples) - elif weighting_method == "inverse": - sample_weights = 1 / task_n_train_examples - elif weighting_method == "inverse_log_example": - sample_weights = 1 / np.log(task_n_train_examples) - elif "examples_proportional_mixing" in weighting_method: - max_K = int(weighting_method.split("K=")[1]) - sample_weights = [min(num_examples, max_K) for num_examples in task_n_train_examples] - elif weighting_method == "inverse_log_batch": - sample_weights = 1 / np.log(task_n_train_batches) - elif "power_" in weighting_method: - weighting_power = float(weighting_method.strip("power_")) - sample_weights = task_n_train_examples ** weighting_power - elif "softmax_" in weighting_method: # exp(x/temp) - weighting_temp = float(weighting_method.strip("softmax_")) - sample_weights = np.exp(task_n_train_examples / weighting_temp) - else: - raise KeyError(f"Unknown weighting method: {weighting_method}") - return sample_weights - - def train( - self, - tasks, - stop_metric, - batch_size, - weighting_method, - scaling_method, - train_params, - optimizer_params, - scheduler_params, - load_model=1, - phase="pretrain", - ): - """ - The main training loop. - Training will stop if we run out of patience or hit the minimum learning rate. - - Parameters - ---------- - tasks: a list of task objects to train on - stop_metric: str, metric to use for early stopping - batch_size: int, batch size to use for the tasks - weighting_method: str, how to sample which task to use - scaling_method: str, how to scale gradients - train_params: trainer config object - optimizer_params: optimizer config object - scheduler_params: scheduler config object - load_model: bool, whether to restore and continue training if a checkpoint is found - phase: str, usually 'pretrain' or 'target_train' - - Returns - ---------- - Validation results - """ - task_infos, metric_infos = self._setup_training( - tasks, batch_size, train_params, optimizer_params, scheduler_params, phase - ) - - optimizer_params = copy.deepcopy(optimizer_params) - if "t_total" in optimizer_params: - # If we know in advance how many opt steps there will be, set it so the LR scheduler - # can use that information. This should be the next validation after we hit the epoch - # limit. - if self._max_epochs > 0: - n_tr_steps_per_epoch = sum([info["n_tr_steps"] for info in task_infos.values()]) - n_vals_in_max_epochs = math.ceil( - (n_tr_steps_per_epoch * self._max_epochs) / self._val_interval - ) - val_limit = min(n_vals_in_max_epochs, self._max_vals) - else: - val_limit = self._max_vals - optimizer_params["t_total"] = val_limit * self._val_interval - - # temporarily increase the log level to avoid some verbose INFO-level logging from AllenNLP - allen_params_log_level = log.getLogger("allennlp.common.params").level - log.getLogger("allennlp.common.params").setLevel(log.WARNING) - self._optimizer = Optimizer.from_params(train_params, optimizer_params) - self._scheduler = LearningRateScheduler.from_params( - self._optimizer, copy.deepcopy(scheduler_params) - ) - log.getLogger("allennlp.common.params").setLevel(allen_params_log_level) - - # define these here b/c they might get overridden on load - n_step, should_stop = 0, False - if self._serialization_dir is not None: - # Resume from serialization path - if load_model: - ckpt_directory, _, _ = check_for_previous_checkpoints( - self._serialization_dir, tasks, phase, load_model - ) - if ckpt_directory is None: - log.warning( - "load_model=1 but there is not checkpoint. \ - Starting training without restoring from a checkpoint." - ) - else: - n_step, should_stop = self._restore_checkpoint(phase, tasks) - log.info("Loaded model from checkpoint. Starting at step %d.", n_step) - else: - log.info("Starting training without restoring from a checkpoint.") - check_for_previous_checkpoints(self._serialization_dir, tasks, phase, load_model) - if self._grad_clipping is not None: # pylint: disable=invalid-unary-operand-type - - def clip_function(grad): - return grad.clamp(-self._grad_clipping, self._grad_clipping) - - for parameter in self._model.parameters(): - if parameter.requires_grad: - parameter.register_hook(clip_function) - - # Calculate per task sampling weights - assert_for_log(len(tasks) > 0, "Error: Expected to sample from 0 tasks.") - - task_names = [task.name for task in tasks] - task_n_train_examples = np.array([task.n_train_examples for task in tasks]) - task_n_train_batches = np.array([task_infos[task.name]["n_tr_batches"] for task in tasks]) - log.info( - "Training examples per task, before any subsampling: " - + str(dict(zip(task_names, task_n_train_examples))) - ) - if len(tasks) > 1: - sample_weights = self.get_sampling_weights( - weighting_method, len(tasks), task_n_train_examples, task_n_train_batches - ) - - normalized_sample_weights = np.array(sample_weights) / sum(sample_weights) - log.info( - "Using weighting method: %s, with normalized sample weights %s ", - weighting_method, - np.array_str(normalized_sample_weights, precision=4), - ) - scaling_weights = self.get_scaling_weights( - scaling_method, len(tasks), task_names, task_n_train_examples - ) - else: - sample_weights = normalized_sample_weights = [1.0] - scaling_weights = {task_names[0]: 1.0} - - # Sample the tasks to train on. Do it all at once (val_interval) for - # MAX EFFICIENCY. - samples = random.choices(tasks, weights=sample_weights, k=self._val_interval) - offset = 0 - all_tr_metrics = {} - log.info("Beginning training with stopping criteria based on metric: %s", stop_metric) - while not should_stop: - self._model.train() - task = samples[(n_step + offset) % self._val_interval] # randomly select a task - task_info = task_infos[task.name] - if task_info["stopped"]: - offset += 1 - continue - # gradients are accumulated for accumulation_steps-many batches before an opt. step: - for batch in itertools.islice(task_info["tr_generator"], self._accumulation_steps): - output_dict = self._forward(batch, task=task) - assert_for_log("loss" in output_dict, "Model must return a dict with 'loss' key") - loss = get_output_attribute(output_dict, "loss", self._cuda_device, "mean") - # Losses are reduced as means. When aggregating loss for accumulation steps, - # losses are divided to calculate mean loss over batches within a step. - if self._accumulation_steps > 1: - loss = loss / self._accumulation_steps - loss *= scaling_weights[task.name] - loss.backward() - assert_for_log(not torch.isnan(loss).any(), "NaNs in loss.") - task_info["loss_since_val"] += loss.data.cpu().numpy() - task_info["n_batches_since_val"] += 1 - task_info["total_batches_trained"] += 1 - - # Gradient regularization and application - if self._grad_norm: - clip_grad_norm_(self._model.parameters(), self._grad_norm) - - self._optimizer.step() - self._optimizer.zero_grad() - task_info["total_steps_trained"] += 1 - task_info["n_steps_since_val"] += 1 - n_step += 1 - - # step scheduler if it's not ReduceLROnPlateau - if not isinstance(self._scheduler.lr_scheduler, ReduceLROnPlateau): - self._scheduler.step_batch(n_step) - - # Intermediate log to logger and tensorboard - if time.time() - task_info["last_log"] > self._log_interval: - task_metrics = task.get_metrics() - avg_loss_per_step_since_val = ( - task_info["loss_since_val"] / task_info["n_steps_since_val"] - ) - # log to tensorboard - if self._TB_dir is not None: - task_metrics_to_TB = task_metrics.copy() - task_metrics_to_TB["loss"] = avg_loss_per_step_since_val - self._metrics_to_tensorboard_tr(n_step, task_metrics_to_TB, task.name) - - task_metrics["%s_loss" % task.name] = avg_loss_per_step_since_val - description = self._description_from_metrics(task_metrics) - log.info( - "Update %d: task %s, steps since last val %d (total steps = %d): %s", - n_step, - task.name, - task_info["n_steps_since_val"], - task_info["total_steps_trained"], - description, - ) - task_info["last_log"] = time.time() - - if get_model_attribute(self._model, "utilization", self._cuda_device) is not None: - batch_util = get_model_attribute( - self._model, "utilization", self._cuda_device - ).get_metric() - log.info("TRAINING BATCH UTILIZATION: %.3f", batch_util) - - # Validation - if n_step % self._val_interval == 0: - # Dump and log all of our current info - n_val = int(n_step / self._val_interval) - log.info("***** Step %d / Validation %d *****", n_step, n_val) - # Get metrics for all training progress so far - for task in tasks: - task_info = task_infos[task.name] - if task_info["n_steps_since_val"] > 0: - task_metrics = task.get_metrics(reset=True) - for name, value in task_metrics.items(): - all_tr_metrics["%s_%s" % (task.name, name)] = value - # Updating loss from training - all_tr_metrics["%s_loss" % task.name] = float( - task_info["loss_since_val"] / task_info["n_steps_since_val"] - ) - else: - all_tr_metrics["%s_loss" % task.name] = 0.0 - log.info( - "%s: trained on %d steps (%d batches) since val, %.3f epochs", - task.name, - task_info["n_steps_since_val"], - task_info["n_batches_since_val"], - task_info["n_steps_since_val"] / task_info["n_tr_steps"], - ) - if get_model_attribute(self._model, "utilization", self._cuda_device) is not None: - batch_util = get_model_attribute( - self._model, "utilization", self._cuda_device - ).get_metric(reset=True) - log.info("TRAINING BATCH UTILIZATION: %.3f", batch_util) - - # Validate - log.info("Validating...") - # this call resets n_steps_since_val, n_batches_since_val, and loss_since_val = 0 - all_val_metrics, should_save, new_best = self._validate(n_val, tasks, batch_size) - - # Check stopping conditions - should_stop = self._check_stop(n_val, stop_metric, tasks) - - # Log results to logger and tensorboard - for name, value in all_val_metrics.items(): - log_str = "%s:" % name - if name in all_tr_metrics: - log_str += " training: %3f" % all_tr_metrics[name] - log_str += " validation: %3f" % value - log.info(log_str) - if self._TB_dir is not None: - self._metrics_to_tensorboard_val(n_step, all_val_metrics) - log.info(f"Global learning rate: {self._optimizer.param_groups[0]['lr']}") - elmo_params = get_model_attribute( - self._model, "get_elmo_mixing_weights", self._cuda_device - )(tasks) - if elmo_params: # log ELMo mixing weights - for task_name, task_params in elmo_params.items(): - log.info("ELMo mixing weights for {}:".format(task_name)) - log.info( - "\t" - + ", ".join( - [ - "{}: {:.6f}".format(layer, float(param)) - for layer, param in task_params.items() - ] - ) - ) - - # Reset training preogress - all_tr_metrics = {} - samples = random.choices( - tasks, weights=sample_weights, k=self._val_interval - ) # pylint: disable=no-member - - if should_save: - self._save_checkpoint( - {"step": n_step, "validation_pass": n_val, "should_stop": should_stop}, - tasks=tasks, - phase=phase, - new_best=new_best, - ) - - log.info("Stopped training after %d validation checks", n_step / self._val_interval) - return self._aggregate_results(tasks, task_infos, metric_infos) # , validation_interval) - - def _aggregate_results(self, tasks, task_infos, metric_infos): - """ Helper function to print results after finishing training """ - results = {} - for task in tasks: - task_info = task_infos[task.name] - log.info( - "Trained %s for %d steps or %.3f epochs", - task.name, - task_info["total_steps_trained"], - task_info["total_steps_trained"] / task_info["n_tr_steps"], - ) - # * validation_interval - results[task.name] = metric_infos[task.val_metric]["best"][0] - # * validation_interval - results["micro"] = metric_infos["micro_avg"]["best"][0] - # * validation_interval - results["macro"] = metric_infos["macro_avg"]["best"][0] - log.info("***** VALIDATION RESULTS *****") - for metric in metric_infos.keys(): - best_val_pass, val_pass_metrics = metric_infos[metric]["best"] - all_metrics_str = ", ".join( - ["%s: %.5f" % (metric, score) for metric, score in val_pass_metrics.items()] - ) - log.info("%s (for best val pass %d): %s", metric, best_val_pass, all_metrics_str) - return results - - def _update_metric_history( - self, - val_pass, - all_val_metrics, - metric, - task_name, - metric_infos, - metric_decreases, - should_save, - new_best, - ): - """ - This function updates metric history with the best validation score so far. - - Parameters - --------- - val_pass: int. - all_val_metrics: dict with performance on current validation pass. - metric: str, name of metric - task_name: str, name of task - metric_infos: dict storing information about the various metrics - metric_decreases: bool, marker to show if we should increase or - decrease validation metric. - should_save: bool, for checkpointing - new_best: bool, indicator of whether the previous best preformance score was exceeded - - Returns - ________ - metric_infos: dict storing information about the various metrics - this_val_metric: dict, metric information for this validation pass, used for optimization - scheduler - should_save: bool - new_best: bool - """ - this_val_metric = all_val_metrics[metric] - metric_history = metric_infos[metric]["hist"] - metric_history.append(this_val_metric) - is_best_so_far, out_of_patience = self._check_history( - metric_history, this_val_metric, metric_decreases - ) - if is_best_so_far: - log.info("Best result seen so far for %s.", task_name) - metric_infos[metric]["best"] = (val_pass, all_val_metrics) - should_save = True - if task_name == "macro": - new_best = True - if out_of_patience: - metric_infos[metric]["stopped"] = True - # Commented out the below line as more confusing than helpful. May make sense to - # restore if we wind up using more complex stopping strategies. - # log.info("Out of early stopping patience. Stopped tracking %s.", task_name) - return metric_infos, this_val_metric, should_save, new_best - - def _calculate_validation_performance( - self, - task, - task_infos, - tasks, - batch_size, - all_val_metrics, - n_examples_overall, - print_output=True, - ): - """ - Builds validation generator, evaluates on each task and produces validation metrics. - - Parameters - ---------- - task: current task to get validation performance of - task_infos: Instance of information about the task (see _setup_training for definition) - tasks: list of task objects to train on - batch_size: int, batch size to use for the tasks - all_val_metrics: dictionary. storing the validation performance - n_examples_overall: int, current number of examples the model is validated on - print_output: bool, prints one example per validation - - Returns - ------- - n_examples_overall: int, current number of examples - task_infos: updated Instance with reset training progress - all_val_metrics: dictinary updated with micro and macro average validation performance - """ - n_examples, batch_num = 0, 0 - task_info = task_infos[task.name] - # to speed up training, we evaluate on a subset of validation data - if self._val_data_limit >= 0: - max_data_points = min(task.n_val_examples, self._val_data_limit) - else: - max_data_points = task.n_val_examples - val_generator = BasicIterator(batch_size, instances_per_epoch=max_data_points)( - task.get_instance_iterable(split_name="val"), num_epochs=1, shuffle=False - ) - n_val_batches = math.ceil(max_data_points / batch_size) - all_val_metrics["%s_loss" % task.name] = 0.0 - - for batch in val_generator: - batch_num += 1 - with torch.no_grad(): - out = self._forward(batch, task=task) - - loss = get_output_attribute(out, "loss", self._cuda_device, "mean") - - all_val_metrics["%s_loss" % task.name] += loss.data.cpu().numpy() - - n_exs = get_output_attribute(out, "n_exs", self._cuda_device) - # in multi-GPU mode n_exs is expected to be a tensor, w/ single-GPU an int is expected: - if isinstance(n_exs, torch.Tensor): - n_examples += n_exs.item() - elif isinstance(n_exs, int): - n_examples += n_exs - else: - raise ValueError("n_exs is type " + type(n_exs) + ", int or Tensor is expected.") - - if print_output: - if isinstance(task, Seq2SeqTask): - if batch_num == 1: - voc_src = self._model.vocab.get_index_to_token_vocabulary("tokens") - voc_trg = self._model.vocab.get_index_to_token_vocabulary( - task.name + "_tokens" - ) - inputs = batch["inputs"]["words"][0][1:] - gold = batch["targs"]["words"][0][1:] - - for i in range(out["predictions"].shape[1]): - output = out["predictions"][0][i] - input_string, gold_string, output_string = task.get_prediction( - voc_src, voc_trg, inputs, gold, output - ) - if i == 0: - log.info("\tInput:\t%s", input_string) - log.info("\tGold:\t%s", gold_string) - log.info("\tOutput:\t%s", output_string) - - # log - if time.time() - task_info["last_log"] > self._log_interval: - task_metrics = task.get_metrics() - task_metrics["%s_loss" % task.name] = ( - all_val_metrics["%s_loss" % task.name] / batch_num - ) - description = self._description_from_metrics(task_metrics) - log.info( - "Evaluate: task %s, batch %d (%d): %s", - task.name, - batch_num, - n_val_batches, - description, - ) - task_info["last_log"] = time.time() - assert batch_num == n_val_batches - - # Get task validation metrics and store in all_val_metrics - task_metrics = task.get_metrics(reset=True) - for name, value in task_metrics.items(): - all_val_metrics["%s_%s" % (task.name, name)] = value - all_val_metrics["%s_loss" % task.name] /= batch_num # n_val_batches - # compute task contribution to macro and micro averages - n_examples_overall += n_examples - if task.val_metric_decreases and len(tasks) > 1: - all_val_metrics["micro_avg"] += ( - 1 - all_val_metrics[task.val_metric] / self._dec_val_scale - ) * n_examples - all_val_metrics["macro_avg"] += ( - 1 - all_val_metrics[task.val_metric] / self._dec_val_scale - ) / len(tasks) - else: - # triggers for single-task cases and during MTL when task val metric increases - all_val_metrics["micro_avg"] += all_val_metrics[task.val_metric] * n_examples - all_val_metrics["macro_avg"] += all_val_metrics[task.val_metric] / len(tasks) - - # Reset training progress - task_info["n_batches_since_val"] = 0 - task_info["n_steps_since_val"] = 0 - task_info["loss_since_val"] = 0 - return n_examples_overall, task_infos, all_val_metrics - - def _validate(self, val_pass, tasks, batch_size, periodic_save=True): - """ - - Validate on all tasks and return the results and whether to save this validation - pass or not. - - Parameters - ---------- - val_pass: int - tasks: list of task objects to train on - batch_size: int, the batch size to use for the tasks.periodic_save - periodic_save: bool, value of whether or not to save model and progress periodically - - Returns - __________ - all_val_metrics: dictinary updated with micro and macro average validation performance - should_save: bool, determines whether to save a checkpoint - new_best: bool, whether or not the macro performance increased - """ - task_infos, metric_infos = self._task_infos, self._metric_infos - self._model.eval() - all_val_metrics = {("%s_loss" % task.name): 0.0 for task in tasks} - all_val_metrics["macro_avg"] = 0.0 - all_val_metrics["micro_avg"] = 0.0 - n_examples_overall = 0.0 - - # Get validation numbers for each task - for task in tasks: - ( - n_examples_overall, - task_infos, - all_val_metrics, - ) = self._calculate_validation_performance( - task, task_infos, tasks, batch_size, all_val_metrics, n_examples_overall - ) - # scale the micro avg contributions w/ total size of validation set. - if "micro_avg" in all_val_metrics: - all_val_metrics["micro_avg"] /= n_examples_overall - # Track per task patience - should_save = periodic_save # whether to save this validation pass or not. - # Currently we save every validation in the main training runs. - new_best = False # whether this validation pass is a new best - - # update metric infos - for task in tasks + ["micro", "macro"]: - if task in ["micro", "macro"]: - metric = "%s_avg" % task - metric_decreases = tasks[0].val_metric_decreases if len(tasks) == 1 else False - task_name = task - else: - metric = task.val_metric - metric_decreases = task.val_metric_decreases - task_name = task.name - if metric_infos[metric]["stopped"]: - continue - metric_infos, this_val_metric, should_save, new_best = self._update_metric_history( - val_pass, - all_val_metrics, - metric, - task_name, - metric_infos, - metric_decreases, - should_save, - new_best, - ) - - # Get scheduler, and update using macro score - # micro has no scheduler updates - if task_name == "macro" and isinstance(self._scheduler.lr_scheduler, ReduceLROnPlateau): - log.info("Updating LR scheduler:") - self._scheduler.step(this_val_metric, val_pass) - log.info( - "\tBest result seen so far for %s: %.3f", - metric, - self._scheduler.lr_scheduler.best, - ) - log.info( - "\t# validation passes without improvement: %d", - self._scheduler.lr_scheduler.num_bad_epochs, - ) - - return all_val_metrics, should_save, new_best - - def _check_stop(self, val_n, stop_metric, tasks): - """ Check to see if should stop """ - task_infos, metric_infos = self._task_infos, self._metric_infos - - should_stop = False - if self._max_epochs > 0: # check if max # epochs hit - for task in tasks: - task_info = task_infos[task.name] - n_epochs_trained = task_info["total_steps_trained"] / task_info["n_tr_steps"] - if n_epochs_trained >= self._max_epochs: - # Commented out the below line as more confusing than helpful. May make sense - # to restore if we wind up using more complex stopping strategies. - # log.info("Reached max_epochs limit for %s.", task.name) - task_info["stopped"] = True - stop_epochs = min([info["stopped"] for info in task_infos.values()]) - if stop_epochs: - log.info("Reached max_epochs limit on all tasks. Stopping training.") - should_stop = True - - if self._optimizer.param_groups[0]["lr"] < self._min_lr: - log.info("Minimum LR reached. Stopping training.") - should_stop = True - - # check if validation metric is stopped - stop_metric = metric_infos[stop_metric]["stopped"] - if stop_metric: - log.info("Ran out of early stopping patience. Stopping training.") - should_stop = True - - # check if max number of validations hit - stop_val = bool(val_n >= self._max_vals) - if stop_val: - log.info("Maximum number of validations reached. Stopping training.") - should_stop = True - - return should_stop - - def _forward(self, batch, task=None): - if isinstance(self._cuda_device, int) and self._cuda_device >= 0: - batch = move_to_device(batch, self._cuda_device) - model_out = self._model.forward(task, batch) - task.update_metrics(model_out, batch) - return model_out - - def _description_from_metrics(self, metrics): - # pylint: disable=no-self-use - """ format some metrics as a string """ - return ", ".join(["%s: %.4f" % (name, value) for name, value in metrics.items()]) - - def _unmark_previous_best(self, phase, val_pass, task_dir_name=""): - marked_best = glob.glob( - os.path.join( - self._serialization_dir, task_dir_name, "*_state_{}_val_*.best.th".format(phase) - ) - ) - for file in marked_best: - # Skip the just-written checkpoint. - if "_{}.".format(val_pass) not in file: - os.rename(file, re.sub("%s$" % (".best.th"), ".th", file)) - - def _delete_old_checkpoints(self, phase, val_pass, task_dir_name=""): - candidates = glob.glob( - os.path.join( - self._serialization_dir, task_dir_name, "*_state_{}_val_*.th".format(phase) - ) - ) - for file in candidates: - # Skip the best, because we'll need it. - # Skip the just-written checkpoint. - if ".best" not in file and "_{}.".format(val_pass) not in file: - os.remove(file) - - def _save_checkpoint(self, training_state, phase="pretrain", new_best=False, tasks=None): - """ - Parameters - ---------- - training_state: An object containing trainer state (step number, etc.), to be saved. - phase: Usually 'pretrain' or 'target_train'. - new_best: If true, the saved checkpoint will be marked with .best_macro, and - potentially used later when switching from pretraining to target task training. - """ - if not self._serialization_dir: - raise ConfigurationError( - "serialization_dir not specified - cannot " - "restore a model without a directory path." - ) - log.info("Saving checkpoints to: %s", self._serialization_dir) - - val_pass = training_state["validation_pass"] - if new_best: - best_str = ".best" - else: - best_str = "" - - task_dir_name = "" - - if phase == "target_train": - # We only pass in one task at a time during target train phase. - assert len(tasks) == 1 - task_dir_name = tasks[0].name - - model_path = os.path.join( - self._serialization_dir, - task_dir_name, - "model_state_{}_val_{}{}.th".format(phase, val_pass, best_str), - ) - - model_state = self._model.state_dict() - - # Skip non-trainable params, like the main ELMo params. - for name, param in self._model.named_parameters(): - if not param.requires_grad: - del model_state[name] - - task_states = {} - for task_name, task_info in self._task_infos.items(): - task_states[task_name] = {} - task_states[task_name]["total_batches_trained"] = task_info["total_batches_trained"] - task_states[task_name]["total_steps_trained"] = task_info["total_steps_trained"] - task_states[task_name]["stopped"] = task_info["stopped"] - task_states["global"] = {} - task_states["global"]["optimizer"] = self._optimizer.state_dict() - # NOTE(Alex): AllenNLP wrapper doesn't expose scheduler state dict methods - task_states["global"]["scheduler"] = self._scheduler.lr_scheduler.state_dict() - - metric_states = {} - for metric_name, metric_info in self._metric_infos.items(): - metric_states[metric_name] = {} - metric_states[metric_name]["hist"] = metric_info["hist"] - metric_states[metric_name]["stopped"] = metric_info["stopped"] - metric_states[metric_name]["best"] = metric_info["best"] - - torch.save( - task_states, - os.path.join( - self._serialization_dir, - task_dir_name, - "task_state_{}_val_{}{}.th".format(phase, val_pass, best_str), - ), - ) - torch.save( - metric_states, - os.path.join( - self._serialization_dir, - task_dir_name, - "metric_state_{}_val_{}{}.th".format(phase, val_pass, best_str), - ), - ) - - torch.save(model_state, model_path) - torch.save( - training_state, - os.path.join( - self._serialization_dir, - task_dir_name, - "training_state_{}_val_{}{}.th".format(phase, val_pass, best_str), - ), - ) - if new_best: - self._unmark_previous_best(phase, val_pass, task_dir_name) - - if not self._keep_all_checkpoints: - self._delete_old_checkpoints(phase, val_pass, task_dir_name) - - def _restore_checkpoint(self, phase, tasks=None): - """ - Restores a model from a serialization_dir to the last saved checkpoint. - This includes a validation pass count and optimizer state, which is serialized separately - from model parameters. This function should only be used to continue training since - it will load previous checkpoints. - - if you wish to load a model for inference/load parts of a model into a new - computation graph, you should use the native Pytorch functions: - `` model.load_state_dict(torch.load("/path/to/model/weights.th"))`` - - We restore based on the phase. If phase=target_train, we start from the last - target task and work backwards, to find the most recent checkpoint in the target - train phase. If phase=pretrain, we check for checkpoints in the main run - directory. - - Returns - ------- - val_pass: the validation pass at which to resume training. - """ - - task_directory, val_pass, suffix = check_for_previous_checkpoints( - self._serialization_dir, tasks, phase, load_model=True - ) - assert val_pass > -1, "No checkpoint found." - log.info("Found checkpoint {}. Loading.".format(suffix)) - if task_directory is None: - task_directory = "" - model_path = os.path.join( - self._serialization_dir, task_directory, "_".join(["model", suffix]) - ) - training_state_path = os.path.join( - self._serialization_dir, task_directory, "_".join(["training", suffix]) - ) - task_state_path = os.path.join( - self._serialization_dir, task_directory, "_".join(["task", suffix]) - ) - metric_state_path = os.path.join( - self._serialization_dir, task_directory, "_".join(["metric", suffix]) - ) - - model_state = torch.load(model_path) - - for name, param in self._model.named_parameters(): - if param.requires_grad and name not in model_state: - log.error("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!") - log.error("Parameter missing from checkpoint: " + name) - log.error("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!") - - self._model.load_state_dict(model_state, strict=False) - task_states = torch.load(task_state_path) - for task_name, task_state in task_states.items(): - if task_name == "global": - continue - self._task_infos[task_name]["total_batches_trained"] = task_state[ - "total_batches_trained" - ] - self._task_infos[task_name]["total_steps_trained"] = task_state["total_steps_trained"] - self._task_infos[task_name]["stopped"] = task_state["stopped"] - generator = self._task_infos[task_name]["tr_generator"] - for _ in itertools.islice( - generator, - task_state["total_batches_trained"] % self._task_infos[task_name]["n_tr_batches"], - ): - pass - self._optimizer.load_state_dict(task_states["global"]["optimizer"]) - # NOTE(Alex): AllenNLP wrapper doesn't expose scheduler state dict methods - self._scheduler.lr_scheduler.load_state_dict(task_states["global"]["scheduler"]) - metric_states = torch.load(metric_state_path) - for metric_name, metric_state in metric_states.items(): - self._metric_infos[metric_name]["hist"] = metric_state["hist"] - self._metric_infos[metric_name]["stopped"] = metric_state["stopped"] - self._metric_infos[metric_name]["best"] = metric_state["best"] - - training_state = torch.load(training_state_path) - return training_state["step"], training_state["should_stop"] - - def _metrics_to_tensorboard_tr(self, val_pass, train_metrics, task_name): - """ - Sends all of the train metrics to tensorboard - """ - metric_names = train_metrics.keys() - - for name in metric_names: - if name == "micro_avg" or name == "macro_avg": - continue - train_metric = train_metrics.get(name) - name = os.path.join(task_name, task_name + "_" + name) - self._TB_train_log.add_scalar(name, train_metric, val_pass) - - def _metrics_to_tensorboard_val(self, val_pass, val_metrics): - """ - Sends all of the val metrics to tensorboard - """ - metric_names = val_metrics.keys() - - for name in metric_names: - if name == "micro_avg" or name == "macro_avg": - continue - val_metric = val_metrics.get(name) - name = os.path.join(name.split("_")[0], name) - self._TB_validation_log.add_scalar(name, val_metric, val_pass) - - @classmethod - def from_params(cls, model, serialization_dir, params): - """ Generate trainer from parameters. """ - - patience = params.pop("patience", 2) - val_interval = params.pop("val_interval", 100) - max_vals = params.pop("max_vals", 50) - cuda_device = params.pop("cuda_device", -1) - grad_norm = params.pop("grad_norm", None) - grad_clipping = params.pop("grad_clipping", None) - lr_decay = params.pop("lr_decay", None) - min_lr = params.pop("min_lr", None) - keep_all_checkpoints = params.pop("keep_all_checkpoints", False) - val_data_limit = params.pop("val_data_limit", 5000) - max_epochs = params.pop("max_epochs", -1) - dec_val_scale = params.pop("dec_val_scale", 100) - training_data_fraction = params.pop("training_data_fraction", 1.0) - accumulation_steps = params.pop("accumulation_steps", 1.0) - - params.assert_empty(cls.__name__) - return SamplingMultiTaskTrainer( - model, - patience=patience, - val_interval=val_interval, - max_vals=max_vals, - serialization_dir=serialization_dir, - cuda_device=cuda_device, - grad_norm=grad_norm, - grad_clipping=grad_clipping, - lr_decay=lr_decay, - min_lr=min_lr, - keep_all_checkpoints=keep_all_checkpoints, - val_data_limit=val_data_limit, - max_epochs=max_epochs, - dec_val_scale=dec_val_scale, - training_data_fraction=training_data_fraction, - accumulation_steps=accumulation_steps, - ) diff --git a/jiant/utils/config.py b/jiant/utils/config.py deleted file mode 100644 index ca7cb6d59..000000000 --- a/jiant/utils/config.py +++ /dev/null @@ -1,157 +0,0 @@ -import argparse -import json -import logging as log -import os -import random -import sys -import time -import types -import re -from typing import Iterable, Sequence, Type, Union - -import pyhocon - -from jiant.utils import hocon_writer - - -log.basicConfig(format="%(asctime)s: %(message)s", datefmt="%m/%d %I:%M:%S %p", level=log.INFO) - - -class Params(object): - """Params handler object. - - This functions as a nested dict, but allows for seamless dot-style access, similar to - tf.HParams but without the type validation. For example: - - p = Params(name="model", num_layers=4) - p.name # "model" - p['data'] = Params(path="file.txt") - p.data.path # "file.txt" - """ - - @staticmethod - def clone(source, strict=True): - if isinstance(source, pyhocon.ConfigTree): - return Params(**source.as_plain_ordered_dict()) - elif isinstance(source, Params): - return Params(**source.as_dict()) - elif isinstance(source, dict): - return Params(**source) - elif strict: - raise ValueError("Cannot clone from type: " + str(type(source))) - else: - return None - - def __getitem__(self, k): - return getattr(self, k) - - def __contains__(self, k): - return k in self._known_keys - - def __setitem__(self, k, v): - assert isinstance(k, str) - if isinstance(self.get(k, None), types.FunctionType): - raise ValueError("Invalid parameter name (overrides reserved name '%s')." % k) - - converted_val = Params.clone(v, strict=False) - if converted_val is not None: - setattr(self, k, converted_val) - else: # plain old data - setattr(self, k, v) - self._known_keys.add(k) - - def __delitem__(self, k): - if k not in self: - raise ValueError("Parameter %s not found.", k) - delattr(self, k) - self._known_keys.remove(k) - - def __init__(self, **kw): - """Create from a list of key-value pairs.""" - self._known_keys = set() - for k, v in kw.items(): - self[k] = v - - def regex_contains(self, k): - """Searches Params for parameters that match a regex.""" - r = re.compile(k) - results = list(filter(r.match, self._known_keys)) - return len(results) > 0 - - def get(self, k, default=None): - return getattr(self, k, default) - - def keys(self): - return sorted(self._known_keys) - - def as_dict(self): - """Recursively convert to a plain dict.""" - - def convert(v): - return v.as_dict() if isinstance(v, Params) else v - - return {k: convert(self[k]) for k in self.keys()} - - def __repr__(self): - return self.as_dict().__repr__() - - def __str__(self): - return json.dumps(self.as_dict(), indent=2, sort_keys=True) - - -def get_task_attr(args: Type[Params], task_name: str, attr_name: str, default=None): - """ Get a task-specific param. - - Look in args.task_name.attr_name, then fall back to default (if provided), - then fall back to args.attr_name. - """ - if task_name in args and (attr_name in args[task_name]): - return args[task_name][attr_name] - if default is not None: - return default - return args[attr_name] - - -def params_from_file(config_files: Union[str, Iterable[str]], overrides: str = None) -> Params: - """Generate config map from config_files and overrides: - - 1) read config file(s) lines (into a str) - 2) append overrides (into str from #1) - 3) call pyhocon's parse_string on combined config-str - 4) return a Params object (a custom jiant config map) - - Parameters - ---------- - config_files : Union[str, Iterable[str]] - filepath(s) for config files. - overrides : str - parameters overriding parameters found in config files. - - Returns - ------- - Params - config map. - - """ - config_string = "" - if isinstance(config_files, str): - config_files = [config_files] - for config_file in config_files: - with open(config_file) as fd: - log.info("Loading config from %s", config_file) - config_string += fd.read() - config_string += "\n" - if overrides: - log.info("Config overrides: %s", overrides) - # Append overrides to file to allow for references and injection. - config_string += "\n" - config_string += overrides - basedir = os.path.dirname(config_file) # directory context for includes - config = pyhocon.ConfigFactory.parse_string(config_string, basedir=basedir) - return Params.clone(config) - - -def write_params(params, config_file): - config = pyhocon.ConfigFactory.from_dict(params.as_dict()) - with open(config_file, "w") as fd: - fd.write(hocon_writer.HOCONConverter.to_hocon(config, indent=2)) diff --git a/jiant/utils/config_handlers.py b/jiant/utils/config_handlers.py new file mode 100644 index 000000000..48471bd3d --- /dev/null +++ b/jiant/utils/config_handlers.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +"""This module contains utilities for manipulating configs.""" +from typing import List + +import json +import _jsonnet # type: ignore + + +def json_merge_patch(target_json: str, patch_json: str) -> str: + """Merge json objects according to JSON merge patch spec: https://tools.ietf.org/html/rfc7396. + + Takes a target json string, and a patch json string and applies the patch json to the target + json according to "JSON Merge Patch" (defined by https://tools.ietf.org/html/rfc7396). + + Args: + target_json: the json to be overwritten by the patch json. + patch_json: the json used to overwrite the target json. + + Returns: + json str after applying the patch json to the target json using "JSON Merge Patch" method. + + """ + merged: str = """local target = {target_json}; + local patch = {patch_json}; + std.mergePatch(target, patch)""".format( + target_json=target_json, patch_json=patch_json + ) + return _jsonnet.evaluate_snippet("snippet", merged) + + +def merge_jsons_in_order(jsons: List[str]) -> str: + """Applies JSON Merge Patch process to a list of json documents in order. + + Takes a list of json document strings and performs "JSON Merge Patch" (see json_merge_patch). + The first element in the list of json docs is treated as the base, subsequent docs (if any) + are applied as patches in order from first to last. + + Args: + jsons: list of json docs to merge into a composite json document. + + Returns: + The composite json document string. + + """ + base_json = jsons.pop(0) + # json.loads is called to check that input strings are valid json. + json.loads(base_json) + composite_json = base_json + for json_str in jsons: + json.loads(json_str) + composite_json = json_merge_patch(composite_json, json_str) + return composite_json diff --git a/jiant/utils/data_handlers.py b/jiant/utils/data_handlers.py new file mode 100644 index 000000000..9baac66f9 --- /dev/null +++ b/jiant/utils/data_handlers.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +"""This module contains utils for handling data (e.g., validating data)""" +import hashlib + + +def md5_checksum(filepath: str) -> str: + """Calculate MD5 checksum hash for a given file. + + Code from example: https://stackoverflow.com/a/3431838/8734015. + + Args: + filepath: file to calculate MD5 checksum. + + Returns: + MD5 hash string. + + """ + hash_md5 = hashlib.md5() + with open(filepath, "rb") as f: + for chunk in iter(lambda: f.read(4096), b""): + hash_md5.update(chunk) + return hash_md5.hexdigest() diff --git a/jiant/utils/data_loaders.py b/jiant/utils/data_loaders.py deleted file mode 100644 index 92e7aa2be..000000000 --- a/jiant/utils/data_loaders.py +++ /dev/null @@ -1,311 +0,0 @@ -""" -Functions having to do with loading data from output of -files downloaded in scripts/download_data_glue.py - -""" -import codecs -import csv -import json -import numpy as np -import pandas as pd -from allennlp.data import vocabulary - -from jiant.utils.tokenizers import get_tokenizer -from jiant.utils.retokenize import realign_spans - - -def load_span_data(tokenizer_name, file_name, label_fn=None, has_labels=True): - """ - Load a span-related task file in .jsonl format, does re-alignment of spans, and tokenizes - the text. - Re-alignment of spans involves transforming the spans so that it matches the text after - tokenization. - For example, given the original text: [Mr., Porter, is, nice] and bert-base-cased - tokenization, we get [Mr, ., Por, ter, is, nice ]. If the original span indices was [0,2], - under the new tokenization, it becomes [0, 3]. - The task file should of be of the following form: - text: str, - label: bool - target: dict that contains the spans - Args: - tokenizer_name: str, - file_name: str, - label_fn: function that expects a row and outputs a transformed row with labels - transformed. - Returns: - List of dictionaries of the aligned spans and tokenized text. - """ - rows = pd.read_json(file_name, lines=True) - # realign spans - rows = rows.apply(lambda x: realign_spans(x, tokenizer_name), axis=1) - if has_labels is False: - rows["label"] = 0 - elif label_fn is not None: - rows["label"] = rows["label"].apply(label_fn) - return list(rows.T.to_dict().values()) - - -def load_pair_nli_jsonl(data_file, tokenizer_name, max_seq_len, targ_map): - """ - Loads a pair NLI task. - - Parameters - ----------------- - data_file: path to data file, - tokenizer_name: str, - max_seq_len: int, - targ_map: a dictionary that maps labels to ints - - Returns - ----------------- - sent1s: list of strings of tokenized first sentences, - sent2s: list of strings of tokenized second sentences, - trgs: list of ints of labels, - idxs: list of ints - """ - data = [json.loads(d) for d in open(data_file, encoding="utf-8")] - sent1s, sent2s, trgs, idxs, pair_ids = [], [], [], [], [] - for example in data: - sent1s.append(tokenize_and_truncate(tokenizer_name, example["premise"], max_seq_len)) - sent2s.append(tokenize_and_truncate(tokenizer_name, example["hypothesis"], max_seq_len)) - trg = targ_map[example["label"]] if "label" in example else 0 - trgs.append(trg) - idxs.append(example["idx"]) - if "pair_id" in example: - pair_ids.append(example["pair_id"]) - return [sent1s, sent2s, trgs, idxs, pair_ids] - - -def load_tsv( - tokenizer_name, - data_file, - max_seq_len, - label_idx=2, - s1_idx=0, - s2_idx=1, - label_fn=None, - skip_rows=0, - return_indices=False, - delimiter="\t", - quote_level=csv.QUOTE_NONE, - filter_idx=None, - has_labels=True, - filter_value=None, - tag_vocab=None, - tag2idx_dict=None, -): - """ - Load a tsv. - - To load only rows that have a certain value for a certain columnn, set filter_idx and - filter_value (for example, for mnli-fiction we want rows where the genre column has - value 'fiction'). - - Args: - tokenizer_name (str): The name of the tokenizer to use (see defaluts.conf for values). - data_file (str): The path to the file to read. - max_seq_len (int): The maximum number of tokens to keep after tokenization, per text field. - Start and end symbols are introduced before tokenization, and are counted, so we will - keep max_seq_len - 2 tokens *of text*. - label_idx (int|None): The column index for the label field, if present. - s1_idx (int): The column index for the first text field. - s2_idx (int|None): The column index for the second text field, if present. - label_fn (fn: str -> int|None): A function to map items in column label_idx to int-valued - labels. - skip_rows (int|list): Skip this many header rows or skip these specific row indices. - has_labels (bool): If False, don't look for labels at position label_idx. - filter_value (str|None): The value in which we want filter_idx to be equal to. - filter_idx (int|None): The column index in which to look for filter_value. - tag_vocab (allennlp vocabulary): In some datasets, examples are attached to tags, and we - need to know the results on examples with certain tags, this is a vocabulary for - tracking tags in a dataset across splits - tag2idx_dict (dict): The tags form a two-level hierarchy, each fine tag belong - to a coarse tag. In the tsv, each coarse tag has one column, the content in that column - indicates what fine tags(seperated by ;) beneath that coarse tag the examples have. - tag2idx_dict is a dictionary to map coarse tag to the index of corresponding column. - e.g. if we have two coarse tags: source at column 0, topic at column 1; and four fine - tags: wiki, reddit beneath source, and economics, politics beneath topic. The tsv will - be: | wiki | economics;politics|, with the tag2idx_dict as {"source": 0, "topic": 1} - | reddit| politics | - - Returns: - List of first and second sentences, labels, and if applicable indices - """ - - # TODO(Yada): Instead of index integers, adjust this to pass in column names - # get the first row as the columns to pass into the pandas reader - # This reads the data file given the delimiter, skipping over any rows - # (usually header row) - rows = pd.read_csv( - data_file, - sep=delimiter, - error_bad_lines=True, - header=None, - skiprows=skip_rows, - quoting=quote_level, - keep_default_na=False, - encoding="utf-8", - ) - - if filter_idx and filter_value: - rows = rows[rows[filter_idx] == filter_value] - # Filter for sentence1s that are of length 0 - # Filter if row[targ_idx] is nan - mask = rows[s1_idx].str.len() > 0 - if s2_idx is not None: - mask = mask & (rows[s2_idx].str.len() > 0) - if has_labels: - mask = mask & rows[label_idx].notnull() - rows = rows.loc[mask] - sent1s = rows[s1_idx].apply(lambda x: tokenize_and_truncate(tokenizer_name, x, max_seq_len)) - if s2_idx is None: - sent2s = pd.Series() - else: - sent2s = rows[s2_idx].apply(lambda x: tokenize_and_truncate(tokenizer_name, x, max_seq_len)) - - label_fn = label_fn if label_fn is not None else (lambda x: x) - if has_labels: - labels = rows[label_idx].apply(lambda x: label_fn(x)) - else: - # If dataset doesn't have labels, for example for test set, then mock labels - labels = np.zeros(len(rows), dtype=int) - if tag2idx_dict is not None: - # -2 offset to cancel @@unknown@@ and @@padding@@ in vocab - def tags_to_tids(coarse_tag, fine_tags): - return ( - [] - if pd.isna(fine_tags) - else ( - [tag_vocab.add_token_to_namespace(coarse_tag) - 2] - + [ - tag_vocab.add_token_to_namespace("%s__%s" % (coarse_tag, fine_tag)) - 2 - for fine_tag in fine_tags.split(";") - ] - ) - ) - - tid_temp = [ - rows[idx].apply(lambda x: tags_to_tids(coarse_tag, x)).tolist() - for coarse_tag, idx in tag2idx_dict.items() - ] - tagids = [[tid for column in tid_temp for tid in column[idx]] for idx in range(len(rows))] - if return_indices: - idxs = rows.index.tolist() - # Get indices of the remaining rows after filtering - return sent1s.tolist(), sent2s.tolist(), labels.tolist(), idxs - elif tag2idx_dict is not None: - return sent1s.tolist(), sent2s.tolist(), labels.tolist(), tagids - else: - return sent1s.tolist(), sent2s.tolist(), labels.tolist() - - -def load_diagnostic_tsv( - tokenizer_name, - data_file, - max_seq_len, - label_col, - s1_col="", - s2_col="", - label_fn=None, - skip_rows=0, - delimiter="\t", -): - """Load a tsv and indexes the columns from the diagnostic tsv. - This is only used for GLUEDiagnosticTask right now. - Args: - data_file: string - max_seq_len: int - s1_col: string - s2_col: string - label_col: string - label_fn: function - skip_rows: list of ints - delimiter: string - Returns: - A dictionary of the necessary indexed fields, the tokenized sent1 and sent2 - and indices - Note: If a field in a particular row in the dataset is empty, we return [] - for that field for that row, otherwise we return an array of ints (indices) - Else, we return an array of indices - """ - # TODO: Abstract indexing layer from this function so that MNLI-diagnostic - # calls load_tsv - assert ( - len(s1_col) > 0 and len(label_col) > 0 - ), "Make sure you passed in column names for sentence 1 and labels" - rows = pd.read_csv( - data_file, sep=delimiter, error_bad_lines=False, quoting=csv.QUOTE_NONE, encoding="utf-8" - ) - rows = rows.fillna("") - - def targs_to_idx(col_name): - # This function builds the index to vocab (and its inverse) mapping - values = set(rows[col_name].values) - vocab = vocabulary.Vocabulary(counter=None, non_padded_namespaces=[col_name]) - for value in values: - vocab.add_token_to_namespace(value, col_name) - idx_to_word = vocab.get_index_to_token_vocabulary(col_name) - word_to_idx = vocab.get_token_to_index_vocabulary(col_name) - rows[col_name] = rows[col_name].apply(lambda x: [word_to_idx[x]] if x != "" else []) - return word_to_idx, idx_to_word, rows[col_name] - - sent1s = rows[s1_col].apply(lambda x: tokenize_and_truncate(tokenizer_name, x, max_seq_len)) - sent2s = rows[s2_col].apply(lambda x: tokenize_and_truncate(tokenizer_name, x, max_seq_len)) - labels = rows[label_col].apply(lambda x: label_fn(x)) - # Build indices for field attributes - lex_sem_to_ix_dic, ix_to_lex_sem_dic, lex_sem = targs_to_idx("Lexical Semantics") - pr_ar_str_to_ix_di, ix_to_pr_ar_str_dic, pr_ar_str = targs_to_idx( - "Predicate-Argument Structure" - ) - logic_to_ix_dic, ix_to_logic_dic, logic = targs_to_idx("Logic") - knowledge_to_ix_dic, ix_to_knowledge_dic, knowledge = targs_to_idx("Knowledge") - idxs = rows.index - - return { - "sents1": sent1s.tolist(), - "sents2": sent2s.tolist(), - "targs": labels.tolist(), - "idxs": idxs.tolist(), - "lex_sem": lex_sem.tolist(), - "pr_ar_str": pr_ar_str.tolist(), - "logic": logic.tolist(), - "knowledge": knowledge.tolist(), - "ix_to_lex_sem_dic": ix_to_lex_sem_dic, - "ix_to_pr_ar_str_dic": ix_to_pr_ar_str_dic, - "ix_to_logic_dic": ix_to_logic_dic, - "ix_to_knowledge_dic": ix_to_knowledge_dic, - } - - -def get_tag_list(tag_vocab): - """ - retrieve tag strings from the tag vocab object - Args: - tag_vocab: the vocab that contains all tags - Returns: - tag_list: a list of "coarse__fine" tag strings - """ - # get dictionary from allennlp vocab, neglecting @@unknown@@ and - # @@padding@@ - tid2tag_dict = { - key - 2: tag - for key, tag in tag_vocab.get_index_to_token_vocabulary().items() - if key - 2 >= 0 - } - tag_list = [ - tid2tag_dict[tid].replace(":", "_").replace(", ", "_").replace(" ", "_").replace("+", "_") - for tid in range(len(tid2tag_dict)) - ] - return tag_list - - -def tokenize_and_truncate(tokenizer_name, sent, max_seq_len): - """Truncate and tokenize a sentence or paragraph.""" - max_seq_len -= 2 # For boundary tokens. - tokenizer = get_tokenizer(tokenizer_name) - - if isinstance(sent, str): - return tokenizer.tokenize(sent)[:max_seq_len] - elif isinstance(sent, list): - assert isinstance(sent[0], str), "Invalid sentence found!" - return sent[:max_seq_len] diff --git a/jiant/utils/display.py b/jiant/utils/display.py new file mode 100644 index 000000000..7c3a88aea --- /dev/null +++ b/jiant/utils/display.py @@ -0,0 +1,43 @@ +import json +from tqdm import auto as tqdm_lib + + +def tqdm(iterable=None, desc=None, total=None, initial=0): + return tqdm_lib.tqdm(iterable=iterable, desc=desc, total=total, initial=initial,) + + +def trange(*args, desc=None, total=None): + return tqdm(range(*args), desc=desc, total=total) + + +def maybe_tqdm(iterable=None, desc=None, total=None, initial=0, verbose=True): + if verbose: + return tqdm(iterable=iterable, desc=desc, total=total, initial=initial) + else: + return iterable + + +def maybe_trange(*args, verbose, **kwargs): + return maybe_tqdm(range(*args), verbose=verbose, **kwargs) + + +def show_json(obj, do_print=True): + string = json.dumps(obj, indent=2) + if do_print: + print(string) + else: + return string + + +def is_notebook(): + try: + # noinspection PyUnresolvedReferences + shell = get_ipython().__class__.__name__ + if shell == "ZMQInteractiveShell": + return True # Jupyter notebook or qtconsole + elif shell == "TerminalInteractiveShell": + return False # Terminal running IPython + else: + return False # Other type (?) + except NameError: + return False # Probably standard Python interpreter diff --git a/jiant/utils/emails.py b/jiant/utils/emails.py deleted file mode 100644 index d3f2eb697..000000000 --- a/jiant/utils/emails.py +++ /dev/null @@ -1,89 +0,0 @@ -# Helpers for sending notification emails using SendGrid. -# Requires 'sendgrid' package: -# pip install sendgrid - -import datetime -import logging as log -import os -import socket -import sys - -import pytz -import sendgrid -from sendgrid.helpers import mail - - -def _read_key_file(fname): - with open(fname) as fd: - return fd.read().strip() - - -# Get API key (shared for workshop account) -SENDGRID_KEY_PATH = "/nfs/jsalt/share/sendgrid.key" -SENDGRID_API_KEY = os.getenv("SENDGRID_API_KEY", None) -if SENDGRID_API_KEY is None: - SENDGRID_API_KEY = _read_key_file(SENDGRID_KEY_PATH) - -DEFAULT_SENDER = mail.Email("jsalt.sentence.rep.2018+notifier@gmail.com", name="Cookie Monster") - -LOCALTZ = pytz.timezone("US/Eastern") - - -def make_message(to: str, subject: str, body: str) -> mail.Mail: - to_email = mail.Email(to) - content = mail.Content("text/plain", body) - return mail.Mail(DEFAULT_SENDER, subject, to_email, content) - - -def send_message(message: mail.Mail): - sg = sendgrid.SendGridAPIClient(apikey=SENDGRID_API_KEY) - response = sg.client.mail.send.post(request_body=message.get()) - return response - - -## -# Implementation-specific logic. - - -def get_notifier(to: str, args): - """ Get a notification handler to call on exit. - - Args: - to: recipient email address - args: config.Params object, main config - - Returns: - function(str, str), call with message body and subject prefix to send a - notification email using sendgrid. - """ - hostname = socket.gethostname() - - def _handler(body: str, prefix: str = ""): - """ Email notifier. Sends an email. """ - # Construct subject line from args: - subj_tmpl = "{prefix:s} '{exp_name:s}/{run_name:s}' on host '{host:s}'" - prefix = prefix + " run" if prefix else "Run" - subject = subj_tmpl.format( - prefix=prefix, host=hostname, exp_name=args.exp_name, run_name=args.run_name - ) - # Add timestamp. - now = datetime.datetime.now(LOCALTZ) - now = now.strftime("%Y-%m-%d %H:%M:%S") - body = f"{now:s} {LOCALTZ.zone:s}\n\n" + body - - # Add log info. - body += "\n\n Experiment log: {:s}".format(args.local_log_path) - try: - from . import gcp - - body += "\n Remote log (if enabled): " + gcp.get_remote_log_url(args.remote_log_name) - except Exception as e: - log.info("Unable to generate remote log URL - not on GCP?") - - # Add experiment args. - body += "\n\n Parsed experiment args: {:s}".format(str(args)) - message = make_message(to, subject, body) - log.info("Sending notification email to %s with subject: \n\t%s", to, subject) - return send_message(message) - - return _handler diff --git a/jiant/utils/gcp.py b/jiant/utils/gcp.py deleted file mode 100644 index ae4e11287..000000000 --- a/jiant/utils/gcp.py +++ /dev/null @@ -1,46 +0,0 @@ -# Helpers for accessing GCP services - -import logging as log # python standard logging -import os - - -def get_instance_id(): - # https://stackoverflow.com/questions/31688646/get-the-name-or-id-of-the-current-google-compute-instance # noqa - import requests - - metadata_server = "http://metadata/computeMetadata/v1/instance/" - metadata_flavor = {"Metadata-Flavor": "Google"} - gce_id = requests.get(metadata_server + "id", headers=metadata_flavor).text - return gce_id - # gce_name = requests.get(metadata_server + 'hostname', headers = metadata_flavor).text - # gce_machine_type = requests.get(metadata_server + 'machine-type', headers = metadata_flavor).text # noqa - - -def get_remote_log_url(log_name, project_name="jsalt-sentence-rep"): - instance_id = get_instance_id() - url = ( - "https://console.cloud.google.com/logs/viewer?" - "authuser=2&project={project_name:s}" - "&resource=gce_instance%2Finstance_id%2F{instance_id:s}" - "&logName=projects%2F{project_name:s}%2Flogs%2F{log_name:s}" - ) - return url.format(instance_id=instance_id, log_name=log_name, project_name=project_name) - - -def configure_remote_logging(log_name): - # Avoid deadlock situation with subprocess. See: - # https://github.com/GoogleCloudPlatform/google-cloud-python/issues/4992 - # and https://github.com/grpc/grpc/issues/14056#issuecomment-370962039 - os.environ["GRPC_ENABLE_FORK_SUPPORT"] = "0" - - # Set up cloud logging - from google.cloud import logging as cloud_logging - from google.cloud.logging.handlers import CloudLoggingHandler - from google.cloud.logging.resource import Resource - - logging_client = cloud_logging.Client() - instance_id = get_instance_id() - log_resource = Resource("gce_instance", {"instance_id": instance_id}) - log.info("Configuring remote logging to %s with log name '%s'", str(log_resource), log_name) - cloud_handler = CloudLoggingHandler(logging_client, name=log_name, resource=log_resource) - log.getLogger().addHandler(cloud_handler) diff --git a/jiant/utils/hocon_writer.py b/jiant/utils/hocon_writer.py deleted file mode 100644 index c6945ef30..000000000 --- a/jiant/utils/hocon_writer.py +++ /dev/null @@ -1,279 +0,0 @@ -# Patched version of HOCON writer, to fix round-trip issues and to sort keys. -# based on https://github.com/chimpler/pyhocon/blob/master/pyhocon/converter.py - -import json -import sys - -from pyhocon import ConfigFactory -from pyhocon.config_tree import ConfigTree, NoneValue - -try: - basestring -except NameError: - basestring = str - - -class HOCONConverter(object): - @classmethod - def to_json(cls, config, compact=False, indent=2, level=0): - """Convert HOCON input into a JSON output - :return: JSON string representation - :type return: basestring - """ - lines = "" - if isinstance(config, ConfigTree): - if len(config) == 0: - lines += "{}" - else: - lines += "{\n" - bet_lines = [] - for key, item in config.items(): - bet_lines.append( - '{indent}"{key}": {value}'.format( - indent="".rjust((level + 1) * indent, " "), - # for dotted keys enclosed with "" to not be - # interpreted as nested key - key=key.strip('"'), - value=cls.to_json(item, compact, indent, level + 1), - ) - ) - lines += ",\n".join(bet_lines) - lines += "\n{indent}}}".format(indent="".rjust(level * indent, " ")) - elif isinstance(config, list): - if len(config) == 0: - lines += "[]" - else: - lines += "[\n" - bet_lines = [] - for item in config: - bet_lines.append( - "{indent}{value}".format( - indent="".rjust((level + 1) * indent, " "), - value=cls.to_json(item, compact, indent, level + 1), - ) - ) - lines += ",\n".join(bet_lines) - lines += "\n{indent}]".format(indent="".rjust(level * indent, " ")) - elif isinstance(config, basestring): - lines = '"{value}"'.format(value=config.replace("\n", "\\n").replace('"', '\\"')) - elif config is None or isinstance(config, NoneValue): - lines = "none" - elif config is True: - lines = "true" - elif config is False: - lines = "false" - else: - lines = str(config) - return lines - - @classmethod - def to_hocon(cls, config, compact=False, indent=2, level=0): - """Convert HOCON input into a HOCON output - :return: JSON string representation - :type return: basestring - """ - lines = "" - if isinstance(config, ConfigTree): - if len(config) == 0: - lines += "{}" - else: - if level > 0: # don't display { at root level - lines += "{\n" - bet_lines = [] - - for key, item in sorted(config.items()): - if compact: - full_key = key - while isinstance(item, ConfigTree) and len(item) == 1: - key, item = next(iter(item.items())) - full_key += "." + key - else: - full_key = key - - bet_lines.append( - "{indent}{key}{assign_sign} {value}".format( - indent="".rjust(level * indent, " "), - key=full_key, - assign_sign="" if isinstance(item, dict) else " =", - value=cls.to_hocon(item, compact, indent, level + 1), - ) - ) - lines += "\n".join(bet_lines) - - if level > 0: # don't display { at root level - lines += "\n{indent}}}".format(indent="".rjust((level - 1) * indent, " ")) - elif isinstance(config, list): - if len(config) == 0: - lines += "[]" - else: - lines += "[\n" - bet_lines = [] - for item in config: - bet_lines.append( - "{indent}{value}".format( - indent="".rjust(level * indent, " "), - value=cls.to_hocon(item, compact, indent, level + 1), - ) - ) - lines += "\n".join(bet_lines) - lines += "\n{indent}]".format(indent="".rjust((level - 1) * indent, " ")) - elif isinstance(config, basestring): - if "\n" in config: - lines = '"""{value}"""'.format(value=config) # multilines - else: - lines = '"{value}"'.format(value=config.replace("\n", "\\n").replace('"', '\\"')) - elif isinstance(config, float): - # don't use scientific notation (e.g. 1e-5) because pyhocon will - # misinterpret it as a string. - lines = "{:f}".format(config) - else: - # serialize POD types as in JSON - lines = json.dumps(config) - # elif config is None or isinstance(config, NoneValue): - # lines = 'none' - # elif config is True: - # lines = 'true' - # elif config is False: - # lines = 'false' - # else: - # lines = str(config) - return lines - - @classmethod - def to_yaml(cls, config, compact=False, indent=2, level=0): - """Convert HOCON input into a YAML output - :return: YAML string representation - :type return: basestring - """ - lines = "" - if isinstance(config, ConfigTree): - if len(config) > 0: - if level > 0: - lines += "\n" - bet_lines = [] - for key, item in config.items(): - bet_lines.append( - "{indent}{key}: {value}".format( - indent="".rjust(level * indent, " "), - # for dotted keys enclosed with "" to not be - # interpreted as nested key, - key=key.strip('"'), - value=cls.to_yaml(item, compact, indent, level + 1), - ) - ) - lines += "\n".join(bet_lines) - elif isinstance(config, list): - config_list = [line for line in config if line is not None] - if len(config_list) == 0: - lines += "[]" - else: - lines += "\n" - bet_lines = [] - for item in config_list: - bet_lines.append( - "{indent}- {value}".format( - indent="".rjust(level * indent, " "), - value=cls.to_yaml(item, compact, indent, level + 1), - ) - ) - lines += "\n".join(bet_lines) - elif isinstance(config, basestring): - # if it contains a \n then it's multiline - lines = config.split("\n") - if len(lines) == 1: - lines = config - else: - lines = "|\n" + "\n".join([line.rjust(level * indent, " ") for line in lines]) - elif config is None or isinstance(config, NoneValue): - lines = "none" - elif config is True: - lines = "true" - elif config is False: - lines = "false" - else: - lines = str(config) - return lines - - @classmethod - def to_properties(cls, config, compact=False, indent=2, key_stack=[]): - """Convert HOCON input into a .properties output - :return: .properties string representation - :type return: basestring - :return: - """ - - def escape_value(value): - return ( - value.replace("=", "\\=") - .replace("!", "\\!") - .replace("#", "\\#") - .replace("\n", "\\\n") - ) - - stripped_key_stack = [key.strip('"') for key in key_stack] - lines = [] - if isinstance(config, ConfigTree): - for key, item in config.items(): - if item is not None: - lines.append( - cls.to_properties(item, compact, indent, stripped_key_stack + [key]) - ) - elif isinstance(config, list): - for index, item in enumerate(config): - if item is not None: - lines.append( - cls.to_properties(item, compact, indent, stripped_key_stack + [str(index)]) - ) - elif isinstance(config, basestring): - lines.append(".".join(stripped_key_stack) + " = " + escape_value(config)) - elif config is True: - lines.append(".".join(stripped_key_stack) + " = true") - elif config is False: - lines.append(".".join(stripped_key_stack) + " = false") - elif config is None or isinstance(config, NoneValue): - pass - else: - lines.append(".".join(stripped_key_stack) + " = " + str(config)) - return "\n".join([line for line in lines if len(line) > 0]) - - @classmethod - def convert(cls, config, output_format="json", indent=2, compact=False): - converters = { - "json": cls.to_json, - "properties": cls.to_properties, - "yaml": cls.to_yaml, - "hocon": cls.to_hocon, - } - - if output_format in converters: - return converters[output_format](config, compact, indent) - else: - raise Exception( - "Invalid format '{format}'. Format must be 'json', 'properties', 'yaml' or 'hocon'".format( # noqa - format=output_format - ) - ) - - @classmethod - def convert_from_file( - cls, input_file=None, output_file=None, output_format="json", indent=2, compact=False - ): - """Convert to json, properties or yaml - :param input_file: input file, if not specified stdin - :param output_file: output file, if not specified stdout - :param output_format: json, properties or yaml - :return: json, properties or yaml string representation - """ - - if input_file is None: - content = sys.stdin.read() - config = ConfigFactory.parse_string(content) - else: - config = ConfigFactory.parse_file(input_file) - - res = cls.convert(config, output_format, indent, compact) - if output_file is None: - print(res) - else: - with open(output_file, "w") as fd: - fd.write(res) diff --git a/jiant/utils/locked_dropout.py b/jiant/utils/locked_dropout.py deleted file mode 100644 index a3b9aa8ea..000000000 --- a/jiant/utils/locked_dropout.py +++ /dev/null @@ -1,19 +0,0 @@ -""" -Module re-used from: https://github.com/yikangshen/Ordered-Neurons -""" -import torch -import torch.nn as nn -from torch.autograd import Variable - - -class LockedDropout(nn.Module): - def __init__(self): - super().__init__() - - def forward(self, x, dropout=0.5): - if not self.training or not dropout: - return x - m = x.data.new(1, x.size(1), x.size(2)).bernoulli_(1 - dropout) - mask = Variable(m, requires_grad=False) / (1 - dropout) - mask = mask.expand_as(x) - return mask * x diff --git a/jiant/utils/options.py b/jiant/utils/options.py deleted file mode 100644 index 25281a1ff..000000000 --- a/jiant/utils/options.py +++ /dev/null @@ -1,60 +0,0 @@ -""" -Functions for parsing configs. -""" -from typing import List - -import torch -import logging as log - -from jiant.tasks import ALL_GLUE_TASKS, ALL_SUPERGLUE_TASKS - - -def parse_task_list_arg(task_list: str) -> List[str]: - """Parse task list argument into a list of task names. - - Parameters - ---------- - task_list : str - comma-delimited list of tasks. - - Returns - ------- - List[str] - List of tasks names. - - """ - task_names = [] - for task_name in task_list.split(","): - if task_name == "glue": - task_names.extend(ALL_GLUE_TASKS) - elif task_name == "superglue": - task_names.extend(ALL_SUPERGLUE_TASKS) - elif task_name == "none" or task_name == "": - continue - else: - task_names.append(task_name) - return task_names - - -def parse_cuda_list_arg(cuda_arg): - """ - Parse cuda_list settings - """ - result_cuda = [] - if cuda_arg == "auto": - result_cuda = list(range(torch.cuda.device_count())) - if len(result_cuda) == 1: - result_cuda = result_cuda[0] - elif len(result_cuda) == 0: - result_cuda = -1 - elif isinstance(cuda_arg, int): - result_cuda = cuda_arg - elif "," in cuda_arg: - result_cuda = [int(d) for d in cuda_arg.split(",")] - else: - raise ValueError( - "Your cuda settings do not match any of the possibilities in defaults.conf" - ) - if torch.cuda.device_count() == 0 and not (isinstance(result_cuda, int) and result_cuda == -1): - raise ValueError("You specified usage of CUDA but CUDA devices not found.") - return result_cuda diff --git a/jiant/utils/path_parse.py b/jiant/utils/path_parse.py new file mode 100644 index 000000000..61e85cfdb --- /dev/null +++ b/jiant/utils/path_parse.py @@ -0,0 +1,98 @@ +import glob +import re + + +def tags_to_regex(tag_pattern, format_dict=None, default_format="\\w+"): + r"""Converts a string with tags to regex. + + E.g. converts + '/path/to/experiments/{model}/{task}' + to + '/path/to/experiments/(?P\\w+)/(?P\\w+)' + + + Args: + tag_pattern: str + String with curly-brackets as tags + format_dict: Dict[str, str] + Special regex formatting for each tag + default_format: str + Default format if not format specified for tag in format_dict + + Returns: str + regex string + """ + if format_dict is None: + format_dict = {} + last_end = 0 + new_tokens = [] + for m in re.finditer("\\{(?P\\w+)\\}", tag_pattern): + start, end = m.span() + tag = m["tag"] + new_tokens.append(tag_pattern[last_end:start]) + tag_format = format_dict.get(tag, default_format) + new_tokens.append(f"(?P<{tag}>{tag_format})") + last_end = end + new_tokens.append(tag_pattern[last_end:]) + new_pattern = "".join(new_tokens) + return new_pattern + + +def match_paths(path_pattern, format_dict=None, default_format="\\w+"): + """Given a pattern, return a list of matches with tag values. + + E.g. converts + '/path/to/experiments/{model}/{task}' + to a list of dicts: + { + "model": ..., + "task": ..., + "path": ..., + } + + Args: + path_pattern: str + Also used as input `tag_pattern` to tags_to_regex + format_dict: Dict[str, str] + See: tags_to_regex + default_format: str + See: tags_to_regex + + Returns: List[dict] + List of matches + """ + path_ls = sorted(glob.glob(re.sub(r"{(\w+)}", "*", path_pattern))) + return match_path_ls( + path_ls=path_ls, + path_pattern=path_pattern, + format_dict=format_dict, + default_format=default_format, + ) + + +def match_path_ls(path_ls, path_pattern, format_dict=None, default_format="\\w+"): + """Matches paths to each pattern + + Args: + path_ls: List[str] + List of paths + path_pattern: str + Input `tag_pattern` to tags_to_regex + format_dict: Dict[str, str] + See: tags_to_regex + default_format: str + See: tags_to_regex + + Returns: List[dict] + List of matches + """ + regex = re.compile( + tags_to_regex(path_pattern, format_dict=format_dict, default_format=default_format,) + ) + result_ls = [] + for path in path_ls: + result = next(regex.finditer(path)).groupdict() + assert "path" not in result, 'keyword clash: "path"' + result["path"] = path + result_ls.append(result) + return result_ls diff --git a/jiant/utils/python/__init__.py b/jiant/utils/python/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/jiant/utils/python/checks.py b/jiant/utils/python/checks.py new file mode 100644 index 000000000..dbb7b8129 --- /dev/null +++ b/jiant/utils/python/checks.py @@ -0,0 +1,12 @@ +from typing import Dict + + +def dict_equal(dict1: Dict, dict2: Dict) -> bool: + if not len(dict1) == len(dict2): + return False + for (k1, v1), (k2, v2) in zip(dict1.items(), dict2.items()): + if k1 != k2: + return False + if v1 != v2: + return False + return True diff --git a/jiant/utils/python/datastructures.py b/jiant/utils/python/datastructures.py new file mode 100644 index 000000000..cffcf734c --- /dev/null +++ b/jiant/utils/python/datastructures.py @@ -0,0 +1,280 @@ +import math +import itertools +from dataclasses import replace +from typing import Mapping, Any, Sequence, Iterable, Iterator, Union, Tuple, Dict, Set + + +def take_one(ls: Union[Sequence, Mapping, Set]) -> Any: + """Extract element from a collection containing just one element. + + Args: + ls (Union[Sequence, Mapping]): collection containing one element. + + Returns: + Element extracted from collection. + + """ + if not len(ls) == 1: + raise IndexError(f"has more than one element ({len(ls)})") + return next(iter(ls)) + + +def chain_idx_get(container: Union[Sequence, Mapping], key_list: Sequence, default: Any) -> Any: + """Get an element at a path in an arbitrarily nested container, return default if not found. + + Args: + container (Union[Sequence, Mapping]): container from which to try to retrieve element. + key_list (Sequence): list of index and/or keys specifying the path. + default (Any): default value to return if no value exists at the specified path. + + Returns: + Element found at the specified path, or default value if no entry is found at that path. + + """ + try: + return chain_idx(container, key_list) + except (KeyError, IndexError, TypeError): + return default + + +def chain_idx(container: Union[Sequence, Mapping], key_list: Sequence) -> Any: + """Get an element at a path in an arbitrarily nested container. + + Args: + container (Union[Sequence, Mapping]): container from which to try to retrieve element. + key_list (Sequence): list of index and/or keys specifying the path. + + Returns: + Element found at the specified path. + + """ + curr = container + for key in key_list: + curr = curr[key] + return curr + + +def group_by(ls: Sequence, key_func) -> dict: + """Group elements by the result of the function applied to each element. + + Args: + ls (Sequence): elements to group. + key_func: function to apply. + + Returns: + Dict grouping elements (values) by the result of the function applied to the element (keys). + + Examples: + group_by([1, 2, 3, 4, 5], lambda x: x%2==0) + # Output: {False: [1, 3, 5], True: [2, 4]} + + """ + result = {} + for elem in ls: + key = key_func(elem) + if key not in result: + result[key] = [] + result[key].append(elem) + return result + + +def combine_dicts(dict_ls: Sequence[dict], strict=True, dict_class=dict): + """Merges entries from one or more dicts into a single dict (shallow copy). + + Args: + dict_ls (Sequence[dict]): sequence of dictionaries to combine. + strict (bool): whether to throw an exception in the event of key collision, else overwrite. + dict_class (dictionary): dictionary class for the destination dict. + + Returns: + Dictionary containing the entries from the input dicts. + + """ + # noinspection PyCallingNonCallable + new_dict = dict_class() + for i, dictionary in enumerate(dict_ls): + for k, v in dictionary.items(): + if strict: + if k in new_dict: + raise RuntimeError(f"repeated key {k} seen in dict {i}") + new_dict[k] = v + return new_dict + + +def sort_dict(d: dict): + return {k: d[k] for k in sorted(list(d.keys()))} + + +def set_dict_keys(d: dict, key_list: list): + """Return a new dictionary with specified key order""" + assert set(d) == set(key_list) + return {k: d[k] for k in key_list} + + +def replace_key(d: dict, old_key, new_key, exist_ok=False): + """Replace an old key with a new key (in-place)""" + if not exist_ok: + assert new_key not in d + d[new_key] = d.pop(old_key) + + +def partition_list(ls, n, strict=False): + length = len(ls) + if strict: + assert length % n == 0 + parts_per = math.ceil(length / n) + print(parts_per) + result = [] + for i in range(n): + result.append(ls[i * parts_per : (i + 1) * parts_per]) + return result + + +class ReusableGenerator(Iterable): + """Makes a generator reusable e.g. + + for x in gen: + pass + for x in gen: + pass + """ + + def __init__(self, generator_function, *args, **kwargs): + self.generator_function = generator_function + self.args = args + self.kwargs = kwargs + + def __iter__(self): + return self.generator_function(*self.args, **self.kwargs) + + +class InfiniteYield(Iterator): + def __init__(self, iterable: Iterable): + self.iterable = iterable + self.iterator = iter(itertools.cycle(self.iterable)) + + def __next__(self): + return next(self.iterator) + + def pop(self): + return next(self.iterator) + + +def has_same_keys(dict1: dict, dict2: dict) -> bool: + return dict1.keys() == dict2.keys() + + +def check_keys(dict1: dict, key_list, mode="equal") -> bool: + dict1_key_set = set(dict1.keys()) + key_set = set(key_list) + assert len(key_set) == len(key_list), "Provided `key_list` is not unique" + if mode == "equal": + return dict1_key_set == key_set + elif mode == "subset": + return dict1_key_set <= key_set + elif mode == "strict_subset": + return dict1_key_set < key_set + elif mode == "superset": + return dict1_key_set >= key_set + elif mode == "strict_superset": + return dict1_key_set > key_set + else: + raise KeyError(mode) + + +def get_unique_list_in_order(list_of_lists: Sequence[Sequence]): + """Gets unique items from a list of lists, in the order of the appearance + + Args: + list_of_lists: list of lists + + Returns: list of unique items in order of appearance + + """ + output = [] + seen = set() + for ls in list_of_lists: + for elem in ls: + if elem not in seen: + output.append(elem) + seen.add(elem) + return output + + +def reorder_keys(dict1: dict, key_list: list) -> dict: + """Returns a dictionary with keys in a given order + + Args: + dict1: a dictionary + key_list: desired key list order + + Returns: + reordered dictionary + + """ + dict_class = dict1.__class__ + assert check_keys(dict1, key_list) + return dict_class([(k, dict1[k]) for k in key_list]) + + +def get_all_same(ls): + assert len(set(ls)) == 1 + return ls[0] + + +def zip_equal(*iterables): + sentinel = object() + for combo in itertools.zip_longest(*iterables, fillvalue=sentinel): + if sentinel in combo: + raise ValueError("Iterables have different lengths") + yield combo + + +class ExtendedDataClassMixin: + @classmethod + def get_fields(cls): + # noinspection PyUnresolvedReferences + return list(cls.__dataclass_fields__) + + @classmethod + def get_annotations(cls): + return cls.__annotations__ + + def to_dict(self): + return {k: getattr(self, k) for k in self.get_fields()} + + @classmethod + def from_dict(cls, kwargs): + # noinspection PyArgumentList + return cls(**kwargs) + + def new(self, **new_kwargs): + # noinspection PyDataclass + return replace(self, **new_kwargs) + + +class BiMap: + """Maintains (bijective) mappings between two sets. + + Args: + a (Sequence): sequence of set a elements. + b (Sequence): sequence of set b elements. + + """ + + def __init__(self, a: Sequence, b: Sequence): + self.a_to_b = {} + self.b_to_a = {} + for i, j in zip(a, b): + self.a_to_b[i] = j + self.b_to_a[j] = i + assert len(self.a_to_b) == len(self.b_to_a) == len(a) == len(b) + + def get_maps(self) -> Tuple[Dict, Dict]: + """Return stored mappings. + + Returns: + Tuple[Dict, Dict]: mappings from elements of a to b, and mappings from b to a. + + """ + return self.a_to_b, self.b_to_a diff --git a/jiant/utils/python/filesystem.py b/jiant/utils/python/filesystem.py new file mode 100644 index 000000000..bb15c8769 --- /dev/null +++ b/jiant/utils/python/filesystem.py @@ -0,0 +1,67 @@ +import os +import importlib +import sys +from contextlib import contextmanager + + +def find_files(base_path, func): + return sorted( + [ + os.path.join(dp, filename) + for dp, dn, filenames in os.walk(base_path) + for filename in filenames + if func(filename) + ] + ) + + +def find_files_with_ext(base_path, ext): + return find_files(base_path=base_path, func=lambda filename: filename.endswith(f".{ext}")) + + +def get_code_base_path(): + """Gets path to root of jiant code base + + Returns: + Path to root of jiant code base + """ + return os.path.abspath(os.path.join(__file__, os.pardir, os.pardir, os.pardir, os.pardir,)) + + +def get_code_asset_path(*rel_path): + """Get path to file/folder within code base + + Like os.path.join, you can supple either arguments: + "path", "to", "file" + or + "path/to/file" + + Args: + *rel_path: one or more strings representing folder/file name, + similar to os.path.join(*rel_path) + + Returns: + Path to file/folder within code base + """ + return os.path.join(get_code_base_path(), *rel_path) + + +def find_case_insensitive_filename(filename, path): + for f in os.listdir(path): + if f.lower() == filename.lower(): + return f + + +@contextmanager +def temporarily_add_sys_path(path): + sys.path = [path] + sys.path + yield + sys.path = sys.path[1:] + + +def import_from_path(path): + base_path, filename = os.path.split(path) + module_name = filename[:-3] if filename.endswith(".py") else filename + with temporarily_add_sys_path(base_path): + module = importlib.import_module(module_name) + return module diff --git a/jiant/utils/python/functional.py b/jiant/utils/python/functional.py new file mode 100644 index 000000000..dd59cc78e --- /dev/null +++ b/jiant/utils/python/functional.py @@ -0,0 +1,32 @@ +from typing import Any + + +def getter(attr_name: Any): + def f(obj): + return getattr(obj, attr_name) + + return f + + +def indexer(key): + def f(obj): + return obj[key] + + return f + + +def identity(*args): + if len(args) > 1: + return args + else: + return args[0] + + +# noinspection PyUnusedLocal +def always_false(*args, **kwargs): + return False + + +# noinspection PyUnusedLocal +def always_true(*args, **kwargs): + return True diff --git a/jiant/utils/python/io.py b/jiant/utils/python/io.py new file mode 100644 index 000000000..33f9fb142 --- /dev/null +++ b/jiant/utils/python/io.py @@ -0,0 +1,92 @@ +import os +import glob +import json + + +def read_file(path, mode="r", **kwargs): + with open(path, mode=mode, **kwargs) as f: + return f.read() + + +def write_file(data, path, mode="w", **kwargs): + with open(path, mode=mode, **kwargs) as f: + f.write(data) + + +def read_json(path): + return json.loads(read_file(path)) + + +def write_json(data, path): + return write_file(json.dumps(data, indent=2), path) + + +def read_jsonl(path): + # Manually open because .splitlines is different from iterating over lines + ls = [] + with open(path, "r") as f: + for line in f: + ls.append(json.loads(line)) + return ls + + +def write_jsonl(data, path): + assert isinstance(data, list) + lines = [to_jsonl(elem) for elem in data] + write_file("\n".join(lines), path) + + +def read_file_lines(path, mode="r", encoding="utf-8", strip_lines=False, **kwargs): + with open(path, mode=mode, encoding=encoding, **kwargs) as f: + lines = f.readlines() + if strip_lines: + return [line.strip() for line in lines] + else: + return lines + + +def read_json_lines(path, mode="r", encoding="utf-8", **kwargs): + with open(path, mode=mode, encoding=encoding, **kwargs) as f: + for line in f.readlines(): + yield json.loads(line) + + +def to_jsonl(data): + return json.dumps(data).replace("\n", "") + + +def create_containing_folder(path): + fol_path = os.path.split(path)[0] + os.makedirs(fol_path, exist_ok=True) + + +def sorted_glob(pathname, *, recursive=False): + return sorted(glob.glob(pathname, recursive=recursive)) + + +def assert_exists(path): + if not os.path.exists(path): + raise FileNotFoundError(path) + + +def assert_not_exists(path): + if os.path.exists(path): + raise FileExistsError(path) + + +def get_num_lines(path): + with open(path, "r") as f: + for i, l in enumerate(f): + pass + return i + 1 + + +def create_dir(*args): + """Makes a folder and returns the path + + Args: + *args: args to os.path.join + """ + path = os.path.join(*args) + os.makedirs(path, exist_ok=True) + return path diff --git a/jiant/utils/python/logic.py b/jiant/utils/python/logic.py new file mode 100644 index 000000000..47441163d --- /dev/null +++ b/jiant/utils/python/logic.py @@ -0,0 +1,18 @@ +from typing import Any, Optional + + +def replace_none(elem: Optional[Any], default: Any): + """If elem is None, return default, else return elem + + Args: + elem: element to possibly return + default: default element + + Returns: + elem, or default + + """ + if elem is None: + return default + else: + return elem diff --git a/jiant/utils/python/strings.py b/jiant/utils/python/strings.py new file mode 100644 index 000000000..419adca08 --- /dev/null +++ b/jiant/utils/python/strings.py @@ -0,0 +1,16 @@ +def remove_prefix(s, prefix): + assert s.startswith(prefix) + return s[len(prefix) :] + + +def remove_suffix(s, suffix): + assert s.endswith(suffix) + return s[: -len(suffix)] + + +def replace_prefix(s, prefix, new_prefix): + return new_prefix + remove_prefix(s, prefix) + + +def replace_suffix(s, suffix, new_suffix): + return remove_suffix(s, suffix) + new_suffix diff --git a/jiant/utils/retokenize.py b/jiant/utils/retokenize.py index 33dec529d..400a9bf28 100644 --- a/jiant/utils/retokenize.py +++ b/jiant/utils/retokenize.py @@ -1,34 +1,18 @@ -# Retokenization helpers. -# Use this to project span annotations from one tokenization to another. -# -# NOTE: please don't make this depend on any other jiant/ libraries; it would -# be nice to opensource this as a standalone utility. -# -# Current implementation is not fast; TODO to profile this and see why. - -import functools -import re -from io import StringIO -from typing import Iterable, List, NewType, Sequence, Text, Tuple, Type, Union +"""Retokenization helpers -import numpy as np -from nltk.tokenize.simple import SpaceTokenizer -from scipy import sparse - -# Use https://pypi.org/project/python-Levenshtein/ for fast alignment. -# install with: pip install python-Levenshtein -from Levenshtein.StringMatcher import StringMatcher +This module provides helpers for projecting span annotations from one tokenization to another. -from jiant.utils.tokenizers import get_tokenizer, Tokenizer -from jiant.utils.utils import unescape_moses, transpose_list_of_lists +Notes: + * Code is ported from https://github.com/nyu-mll/jiant/blob/master/jiant/utils/retokenize.py + * Please keep this code as a standalone utility; don't make this module depend on jiant modules. +""" +from typing import Iterable, Sequence, Tuple, Union -# Tokenizer instance for internal use. -_SIMPLE_TOKENIZER = SpaceTokenizer() -_SEP = " " # should match separator used by _SIMPLE_TOKENIZER +from Levenshtein.StringMatcher import StringMatcher +from nltk.tokenize.util import string_span_tokenize +import numpy as np -# Type alias for internal matricies -Matrix = NewType("Matrix", Union[Type[sparse.csr_matrix], Type[np.ndarray]]) _DTYPE = np.int32 @@ -50,32 +34,7 @@ def _mat_from_blocks_dense(mb, n_chars_src, n_chars_tgt): return M -def _mat_from_blocks_sparse(mb, n_chars_src, n_chars_tgt): - ridxs = [] - cidxs = [] - data = [] - for i, b in enumerate(mb): - # Fill in-between this block and last block - if i > 0: - lb = mb[i - 1] # last block - s0 = lb[0] + lb[2] # top - l0 = b[0] - s0 # num rows - s1 = lb[1] + lb[2] # left - l1 = b[1] - s1 # num cols - idxs = np.indices((l0, l1)) - ridxs.extend((s0 + idxs[0]).flatten()) # row indices - cidxs.extend((s1 + idxs[1]).flatten()) # col indices - data.extend(np.ones(l0 * l1, dtype=_DTYPE)) - - # Fill matching region on diagonal - ridxs.extend(range(b[0], b[0] + b[2])) - cidxs.extend(range(b[1], b[1] + b[2])) - data.extend(2 * np.ones(b[2], dtype=_DTYPE)) - M = sparse.csr_matrix((data, (ridxs, cidxs)), shape=(n_chars_src, n_chars_tgt)) - return M - - -def _mat_from_spans_dense(spans: Sequence[Tuple[int, int]], n_chars: int) -> Matrix: +def _mat_from_spans_dense(spans: Sequence[Tuple[int, int]], n_chars: int) -> np.ndarray: """Construct a token-to-char matrix from a list of char spans.""" M = np.zeros((len(spans), n_chars), dtype=_DTYPE) for i, s in enumerate(spans): @@ -83,353 +42,236 @@ def _mat_from_spans_dense(spans: Sequence[Tuple[int, int]], n_chars: int) -> Mat return M -def _mat_from_spans_sparse(spans: Sequence[Tuple[int, int]], n_chars: int) -> Matrix: - """Construct a token-to-char matrix from a list of char spans.""" - ridxs = [] - cidxs = [] - for i, s in enumerate(spans): - ridxs.extend([i] * (s[1] - s[0])) # repeat token index - cidxs.extend(range(s[0], s[1])) # char indices - # assert len(ridxs) == len(cidxs) - data = np.ones(len(ridxs), dtype=_DTYPE) - return sparse.csr_matrix((data, (ridxs, cidxs)), shape=(len(spans), n_chars)) +def token_to_char(text: str, sep=" ") -> np.ndarray: + """Takes a string, space tokenizes the string, and returns a mapping from tokens to chars. + Examples: + >>> token_to_char("testing 1, 2, 3") + # produces a (m) token by (M) char matrix: + + t e s t i n g 1 , 2 , 3 + testing [[1 1 1 1 1 1 1 0 0 0 0 0 0 0 0] + 1, [0 0 0 0 0 0 0 0 1 1 0 0 0 0 0] + 2, [0 0 0 0 0 0 0 0 0 0 0 1 1 0 0] + 3 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 1]] + + Args: + text (str): string to tokenize and build the token to char mapping. + + Returns: + np.ndarray mapping from (m) tokens to (M) chars. -def realign_spans(record, tokenizer_name): """ - Builds the indices alignment while also tokenizing the input - piece by piece. - Currently, SentencePiece (for XLNet), WPM (for BERT), BPE (for GPT/XLM), - ByteBPE (for RoBERTa/GPT-2) and Moses (for Transformer-XL and default) tokenization are - supported. - - Parameters - ----------------------- - record: dict with the below fields - text: str - targets: list of dictionaries - label: bool - span1_index: int, start index of first span - span1_text: str, text of first span - span2_index: int, start index of second span - span2_text: str, text of second span - tokenizer_name: str - - Returns - ------------------------ - record: dict with the below fields: - text: str in tokenized form - targets: dictionary with the below fields - -label: bool - -span_1: (int, int) of token indices - -span1_text: str, the string - -span2: (int, int) of token indices - -span2_text: str, the string + spans = string_span_tokenize(text, sep=sep) + return _mat_from_spans_dense(tuple(spans), len(text)) + + +def _mat_from_blocks( + mb: Sequence[Tuple[int, int, int]], n_chars_src: int, n_chars_tgt: int +) -> np.ndarray: + """Construct a char-to-char matrix from a list of matching blocks. + + mb is a sequence of (s1, s2, n_char) tuples, where s1 and s2 are the start indices in the + first and second sequence, and n_char is the length of the block. + + Args: + mb: list of triples of non-overlapping matching subsequences in source str and target. + n_chars_src (int): number of chars in the source string. + n_chars_tgt (int): number of chars in the target string. + + Returns: + np.ndarray adjacency matrix mapping chars in the source str to chars in the target str. + """ + return _mat_from_blocks_dense(mb, n_chars_src, n_chars_tgt) - # find span indices and text - text = record["text"].split() - span1 = record["target"]["span1_index"] - span1_text = record["target"]["span1_text"] - span2 = record["target"]["span2_index"] - span2_text = record["target"]["span2_text"] - - # construct end spans given span text space-tokenized length - span1 = [span1, span1 + len(span1_text.strip().split())] - span2 = [span2, span2 + len(span2_text.strip().split())] - indices = [span1, span2] - - sorted_indices = sorted(indices, key=lambda x: x[0]) - current_tokenization = [] - span_mapping = {} - - # align first span to tokenized text - aligner_fn = get_aligner_fn(tokenizer_name) - _, new_tokens = aligner_fn(" ".join(text[: sorted_indices[0][0]])) - current_tokenization.extend(new_tokens) - new_span1start = len(current_tokenization) - _, span_tokens = aligner_fn(" ".join(text[sorted_indices[0][0] : sorted_indices[0][1]])) - current_tokenization.extend(span_tokens) - new_span1end = len(current_tokenization) - span_mapping[sorted_indices[0][0]] = [new_span1start, new_span1end] - - # re-indexing second span - _, new_tokens = aligner_fn(" ".join(text[sorted_indices[0][1] : sorted_indices[1][0]])) - current_tokenization.extend(new_tokens) - new_span2start = len(current_tokenization) - _, span_tokens = aligner_fn(" ".join(text[sorted_indices[1][0] : sorted_indices[1][1]])) - current_tokenization.extend(span_tokens) - new_span2end = len(current_tokenization) - span_mapping[sorted_indices[1][0]] = [new_span2start, new_span2end] - - # save back into record - _, all_text = aligner_fn(" ".join(text)) - record["target"]["span1"] = span_mapping[record["target"]["span1_index"]] - record["target"]["span2"] = span_mapping[record["target"]["span2_index"]] - record["text"] = " ".join(all_text) - return record + +def char_to_char(source: str, target: str) -> np.ndarray: + """Find the character adjacency matrix mapping source string chars to target string chars. + + Uses StringMatcher from Levenshtein package to find non-overlapping matching subsequences in + input strings. Uses the result to create a character adjacency matrix from source to target. + (https://docs.python.org/2/library/difflib.html#difflib.SequenceMatcher.get_matching_blocks) + + Args: + source (str): string of source chars. + target (str): string of target chars. + + Returns: + np.ndarray adjacency matrix mapping chars in the source str to chars in the target str. + + """ + sm = StringMatcher(seq1=source, seq2=target) + mb = sm.get_matching_blocks() + return _mat_from_blocks(mb, len(source), len(target)) class TokenAligner(object): """Align two similiar tokenizations. + Args: + source (Union[Iterable[str], str]): Source text tokens or string. + target (Union[Iterable[str], str]): Target text tokens or string. + Usage: ta = TokenAligner(source_tokens, target_tokens) target_span = ta.project_span(*source_span) - Uses Levenshtein distance to align two similar tokenizations, and provide - facilities to project indices and spans from the source tokenization to the - target. + Uses Levenshtein distance to align two similar tokenizations, and provide facilities to project + indices and spans from the source tokenization to the target. - Let source contain m tokens and M chars, and target contain n tokens and N - chars. The token alignment is treated as a (sparse) m x n adjacency matrix - T representing the bipartite graph between the source and target tokens. + Let source contain m tokens and M chars, and target contain n tokens and N chars. The token + alignment is treated as a (sparse) m x n adjacency matrix T representing the bipartite graph + between the source and target tokens. - This is constructed by performing a character-level alignment using - Levenshtein distance to obtain a (M x N) character adjacency matrix C. We - then construct token-to-character matricies U (m x M) and V (n x N) and - construct T as: + This is constructed by performing a character-level alignment using Levenshtein distance to + obtain a (M x N) character adjacency matrix C. We then construct token-to-character matricies + U (m x M) and V (n x N) and construct T as: T = (U C V') where V' denotes the transpose. - Spans of non-aligned bytes are assumed to contain a many-to-many alignment - of all chars in that range. This can lead to unwanted alignments if, for - example, two consecutive tokens are mapped to escape sequences: + Spans of non-aligned bytes are assumed to contain a many-to-many alignment of all chars in that + range. This can lead to unwanted alignments if, for example, two consecutive tokens are mapped + to escape sequences: source: ["'s", "["] target: ["'", "s", "["] - In the above case, "'s'" may be spuriously aligned to "'" while "[" - has no character match with "s" or "[", and so is aligned to both. To - make a correct alignment more likely, ensure that the characters in target - correspond as closely as possible to those in source. For example, the - following will align correctly: + In the above case, "'s'" may be spuriously aligned to "'" while "[" has no character match + with "s" or "[", and so is aligned to both. To make a correct alignment more likely, ensure + that the characters in target correspond as closely as possible to those in source. For example, + the following will align correctly: source: ["'s", "["] target: ["'", "s", "["] - """ - def token_to_char(self, text: str) -> Matrix: - spans = _SIMPLE_TOKENIZER.span_tokenize(text) - # TODO(iftenney): compare performance of these implementations. - return _mat_from_spans_sparse(tuple(spans), len(text)) - # return _mat_from_spans_dense(tuple(spans), len(text)) - - def _mat_from_blocks( - self, mb: Sequence[Tuple[int, int, int]], n_chars_src: int, n_chars_tgt: int - ) -> Matrix: - """Construct a char-to-char matrix from a list of matching blocks. - - mb is a sequence of (s1, s2, n_char) tuples, where s1 and s2 are the - start indices in the first and second sequence, and n_char is the - length of the block. - """ - # TODO(iftenney): compare performance of these implementations. - # return _mat_from_blocks_sparse(mb, n_chars_src, n_chars_tgt) - return _mat_from_blocks_dense(mb, n_chars_src, n_chars_tgt) - - def char_to_char(self, source: str, target: str) -> Matrix: - # Run Levenshtein at character level. - sm = StringMatcher(seq1=source, seq2=target) - mb = sm.get_matching_blocks() - return self._mat_from_blocks(mb, len(source), len(target)) + """ def __init__(self, source: Union[Iterable[str], str], target: Union[Iterable[str], str]): # Coerce source and target to space-delimited string. if not isinstance(source, str): - source = _SEP.join(source) + source = " ".join(source) if not isinstance(target, str): - target = _SEP.join(target) - - self.U = self.token_to_char(source) # (M x m) - self.V = self.token_to_char(target) # (N x n) - # Character transfer matrix (M x N) - self.C = self.char_to_char(source, target) - # Token transfer matrix (m x n) - self.T = self.U * self.C * self.V.T - # self.T = self.U.dot(self.C).dot(self.V.T) - - def __str__(self): - return self.pprint() - - def pprint(self, src_tokens=None, tgt_tokens=None) -> str: - """Render as alignment table: src -> [tgts]""" - output = StringIO() - output.write("{:s}({:d}, {:d}):\n".format(self.__class__.__name__, *self.T.shape)) - for i in range(self.T.shape[0]): - targs = sorted(list(self.project_tokens(i))) - output.write(" {:d} -> {:s}".format(i, str(targs))) - if src_tokens is not None and tgt_tokens is not None: - tgt_list = [tgt_tokens[j] for j in targs] - output.write("\t'{:s}' -> {:s}".format(src_tokens[i], str(tgt_list))) - output.write("\n") - return output.getvalue() - - def project_tokens(self, idxs: Union[int, Sequence[int]]) -> Sequence[int]: - """Project source token indices to target token indices.""" + target = " ".join(target) + self.U = token_to_char(source) # (m X M) source token idx to source char idx + self.V = token_to_char(target) # (n x N) target token idx to target char idx + self.C = char_to_char(source, target) # (M x N) source char idx to target char idx + # Token transfer matrix from (m) tokens in source to (n) tokens in the target. Mat value at + # index i, j measures the character overlap btwn the ith source token and jth target token. + self.source_token_idx_to_target_token_idx = self.U.dot(self.C).dot(self.V.T) + self.source_token_idx_to_target_char_idx = self.U.dot(self.C) + self.source_char_idx_to_target_token_idx = self.C.dot(self.V.T) + + def project_token_idxs(self, idxs: Union[int, Sequence[int]]) -> Sequence[int]: + """Project source token index(s) to target token indices. + + Takes a list of token indices in the source token sequence, and returns the corresponding + tokens in the target sequence. + + Args: + idxs (Union[int, Sequence[int]]): source token index(s) to get related target indices. + + Examples: + >>> source_tokens = ['abc', 'def', 'ghi', 'jkl'] + >>> target_tokens = ['abc', 'd', 'ef', 'ghi', 'jkl'] + >>> ta = TokenAligner(source_tokens, target_tokens) + >>> print(ta.project_token_idxs([1, 2])) + [1 2 3] + + Returns: + List[int] representing the target indices associated with the provided source indices. + + """ if isinstance(idxs, int): idxs = [idxs] - return self.T[idxs].nonzero()[1] # column indices - - def project_span(self, start, end) -> Tuple[int, int]: - """Project a span from source to target. - - Span end is taken to be exclusive, so this actually projects end - 1 - and maps back to an exclusive target span. + return self.source_token_idx_to_target_token_idx[idxs].nonzero()[1] # column indices + + @staticmethod + def _project_span(mat, start, end, inclusive): + if inclusive: + end = end + 1 + target_matches = mat[start:end].nonzero()[1].tolist() + if len(target_matches) == 0: + raise ValueError(f"Project {(start, end)} into empty span in target sequence") + output_start, output_end = min(target_matches), max(target_matches) + if not inclusive: + output_end = output_end + 1 + return (output_start, output_end) + + def project_token_span(self, start, end, inclusive=False) -> Tuple[int, int]: + """Project a span from source to target token sequence. + + Notes: + When param inclusive=False, the end index is interpreted as exclusive, + and the end of the span returned by the function will also be exclusive. + When param inclusive=True, both start and end indexes are interpreted as inclusive, + and the span returned by the function will also be inclusive. + + Examples: + >>> source_tokens = ['abc', 'def', 'ghi', 'jkl'] + >>> target_tokens = ['abc', 'd', 'ef', 'ghi', 'jkl'] + >>> ta = TokenAligner(source_tokens, target_tokens) + >>> start, end = 0, 2 + >>> print(ta.project_token_span(start, end)) + (0, 3) + + Raise: + When target span is empty + + Returns: + Tuple[int, int] representing the target span corresponding to the source span. """ - tgt_idxs = self.project_tokens([start, end - 1]) - return min(tgt_idxs), max(tgt_idxs) + 1 - - -## -# Aligner functions. These take a raw string and return a tuple -# of a TokenAligner instance and a list of tokens. -## - - -def space_tokenize_with_eow(sentence): - """Add markers to ensure word-boundary alignment.""" - return [t + "" for t in sentence.split()] - - -def process_wordpiece_for_alignment(t): - """Add markers to ensure word-boundary alignment.""" - if t.startswith("##"): - return re.sub(r"^##", "", t) - else: - return "" + t - - -def process_sentencepiece_for_alignment(t): - """Add markers to ensure word-boundary alignment.""" - if t.startswith("▁"): - return "" + re.sub(r"^▁", "", t) - else: - return t - - -def process_bytebpe_for_alignment(t): - """Add markers to ensure word-boundary alignment.""" - if t.startswith("Ġ"): - return "" + re.sub(r"^Ġ", "", t) - else: - return t - - -def space_tokenize_with_bow(sentence): - """Add markers to ensure word-boundary alignment.""" - return ["" + t for t in sentence.split()] - - -def align_moses(text: Text) -> Tuple[TokenAligner, List[Text]]: - """Aligner fn for Moses tokenizer, used in Transformer-XL - """ - MosesTokenizer = get_tokenizer("MosesTokenizer") - moses_tokens = MosesTokenizer.tokenize(text) - cleaned_moses_tokens = unescape_moses(moses_tokens) - ta = TokenAligner(text, cleaned_moses_tokens) - return ta, moses_tokens + return self._project_span( + mat=self.source_token_idx_to_target_token_idx, start=start, end=end, inclusive=inclusive + ) + def project_token_to_char_span(self, start, end, inclusive=False) -> Tuple[int, int]: + """Project a span from source to target token sequence. -def align_wpm( - text: Text, wpm_tokenizer: Tokenizer, do_lower_case: bool -) -> Tuple[TokenAligner, List[Text]]: - """Alignment fn for WPM tokenizer, used in BERT - """ - # If using lowercase, do this for the source tokens for better matching. - bow_tokens = space_tokenize_with_bow(text.lower() if do_lower_case else text) - wpm_tokens = wpm_tokenizer.tokenize(text) + Notes: + When param inclusive=False, the end index is interpreted as exclusive, + and the end of the span returned by the function will also be exclusive. + When param inclusive=True, both start and end indexes are interpreted as inclusive, + and the span returned by the function will also be inclusive. - # Align using markers for stability w.r.t. word boundaries. - modified_wpm_tokens = list(map(process_wordpiece_for_alignment, wpm_tokens)) - ta = TokenAligner(bow_tokens, modified_wpm_tokens) - return ta, wpm_tokens + Examples: + >>> source_tokens = ['abc', 'def', 'ghi', 'jkl'] + >>> target_str = 'abc d ef ghi jkl' + >>> ta = TokenAligner(source_tokens, target_str) + >>> start, end = 0, 2 + >>> print(ta.project_token_to_char_span(start, end)) + (0, 8) + Raise: + When target span is empty -def align_sentencepiece( - text: Text, sentencepiece_tokenizer: Tokenizer -) -> Tuple[TokenAligner, List[Text]]: - """Alignment fn for SentencePiece Tokenizer, used in XLNET and ALBERT - """ - bow_tokens = space_tokenize_with_bow(text) - sentencepiece_tokens = sentencepiece_tokenizer.tokenize(text) + Returns: + Tuple[int, int] representing the target span corresponding to the source span. + """ + return self._project_span( + mat=self.source_token_idx_to_target_char_idx, start=start, end=end, inclusive=inclusive + ) - modified_sentencepiece_tokens = list( - map(process_sentencepiece_for_alignment, sentencepiece_tokens) - ) - ta = TokenAligner(bow_tokens, modified_sentencepiece_tokens) - return ta, sentencepiece_tokens + def project_char_to_token_span(self, start, end, inclusive=False) -> Tuple[int, int]: + """Project a span from source to target token sequence. + Notes: + When param inclusive=False, the end index is interpreted as exclusive, + and the end of the span returned by the function will also be exclusive. + When param inclusive=True, both start and end indexes are interpreted as inclusive, + and the span returned by the function will also be inclusive. -def align_bpe(text: Text, bpe_tokenizer: Tokenizer) -> Tuple[TokenAligner, List[Text]]: - """Alignment fn for BPE tokenizer, used in GPT and XLM - """ - eow_tokens = space_tokenize_with_eow(text.lower()) - bpe_tokens = bpe_tokenizer.tokenize(text) - ta = TokenAligner(eow_tokens, bpe_tokens) - return ta, bpe_tokens + Examples: + >>> source_str = 'abc def ghi jkl' + >>> target_tokens = ['abc', 'd', 'ef', 'ghi', 'jkl'] + >>> ta = TokenAligner(source_str, target_tokens) + >>> start, end = 0, 4 + >>> print(ta.project_char_to_token_span(start, end)) + (0, 1) + Raise: + When target span is empty -def align_bytebpe(text: Text, bytebpe_tokenizer: Tokenizer) -> Tuple[TokenAligner, List[Text]]: - """Alignment fn for Byte-level BPE tokenizer, used in GPT-2 and RoBERTa - """ - bow_tokens = space_tokenize_with_bow(text) - bytebpe_tokens = bytebpe_tokenizer.tokenize(text) - - if len(bytebpe_tokens) > 0: - bytebpe_tokens[0] = "Ġ" + bytebpe_tokens[0] - modified_bytebpe_tokens = list(map(process_bytebpe_for_alignment, bytebpe_tokens)) - ta = TokenAligner(bow_tokens, modified_bytebpe_tokens) - if len(bytebpe_tokens) > 0: - bytebpe_tokens[0] = re.sub(r"^Ġ", "", bytebpe_tokens[0]) - return ta, bytebpe_tokens - - -def get_aligner_fn(tokenizer_name: Text): - """Given the tokenzier_name, return the corresponding alignment function. - An alignment function modified the tokenized input to make it close to source token, - and choose a space tokenizer with its word-boundary at the same side as tokenizer_name, - hence the source (from space tokenizer) and target (from tokenizer_name) is sufficiently close. - Use TokenAligner to project token index from source to target. - """ - if tokenizer_name == "MosesTokenizer" or tokenizer_name.startswith("transfo-xl-"): - return align_moses - elif tokenizer_name.startswith("bert-"): - do_lower_case = tokenizer_name.endswith("uncased") - wpm_tokenizer = get_tokenizer(tokenizer_name) - return functools.partial( - align_wpm, wpm_tokenizer=wpm_tokenizer, do_lower_case=do_lower_case - ) - elif tokenizer_name.startswith("openai-gpt") or tokenizer_name.startswith("xlm-mlm-en-"): - bpe_tokenizer = get_tokenizer(tokenizer_name) - return functools.partial(align_bpe, bpe_tokenizer=bpe_tokenizer) - elif tokenizer_name.startswith("xlnet-") or tokenizer_name.startswith("albert-"): - sentencepiece_tokenizer = get_tokenizer(tokenizer_name) - return functools.partial( - align_sentencepiece, sentencepiece_tokenizer=sentencepiece_tokenizer + Returns: + Tuple[int, int] representing the target span corresponding to the source span. + """ + return self._project_span( + mat=self.source_char_idx_to_target_token_idx, start=start, end=end, inclusive=inclusive ) - elif ( - tokenizer_name.startswith("roberta-") - or tokenizer_name.startswith("nyu-mll/roberta-") - or tokenizer_name.startswith("gpt2") - ): - bytebpe_tokenizer = get_tokenizer(tokenizer_name) - return functools.partial(align_bytebpe, bytebpe_tokenizer=bytebpe_tokenizer) - else: - raise ValueError(f"Unsupported tokenizer '{tokenizer_name}'") - - -def space_tokenize_with_spans(text): - space_tokens = text.split() - result = [] - i = 0 - for token in space_tokens: - start = text[i:].find(token) - end = start + len(token) - result.append((token, i + start, i + end)) - i += end - return result - - -def find_space_token_span(space_tokens_with_spans, char_start, char_end): - starts, ends = transpose_list_of_lists(space_tokens_with_spans)[1:] - tok_start = np.clip((np.array(starts) > char_start).argmax() - 1, 0, None) - tok_end = (np.array(ends) > (char_end - 1)).argmax() + 1 - return tok_start, tok_end diff --git a/jiant/utils/serialize.py b/jiant/utils/serialize.py deleted file mode 100644 index cd69252a5..000000000 --- a/jiant/utils/serialize.py +++ /dev/null @@ -1,86 +0,0 @@ -# Serialization and deserialization helpers. -# Write arbitrary pickle-able Python objects to a record file, with one object -# per line as a base64-encoded pickle. - -import _pickle as pkl -import base64 -from zlib import crc32 - - -def _serialize(examples, fd, flush_every): - for i, example in enumerate(examples): - blob = pkl.dumps(example) - encoded = base64.b64encode(blob) - fd.write(encoded) - fd.write(b"\n") - if (i + 1) % flush_every == 0 and hasattr(fd, "flush"): - fd.flush() - - -def write_records(examples, filename, flush_every=10000): - """Streaming read records from file. - - Args: - examples: iterable(object), iterable of examples to write - filename: path to file to write - flush_every: (int), flush to disk after this many examples consumed - """ - with open(filename, "wb") as fd: - _serialize(examples, fd, flush_every) - - -class RepeatableIterator(object): - """Repeatable iterator class.""" - - def __init__(self, iter_fn): - """Create a repeatable iterator. - - Args: - iter_fn: callable with no arguments, creates an iterator - """ - self._iter_fn = iter_fn - self._counter = 0 - - def get_counter(self): - return self._counter - - def __iter__(self): - self._counter += 1 - return self._iter_fn().__iter__() - - -def bytes_to_float(b): - """ Maps a byte string to a float in [0, 1]. - - Verified to be uniform, at least over text strings and zero byte strings of varying lengths. - """ - return float(crc32(b) & 0xFFFFFFFF) / 2 ** 32 - - -def read_records(filename, repeatable=False, fraction=None): - """Streaming read records from file. - - Args: - filename: path to file of b64-encoded pickles, one per line - repeatable: if true, returns a RepeatableIterator that can read the file - multiple times. - fraction: if set to a float between 0 and 1, load only the specified percentage - of examples. Hashing is used to ensure that the same examples are loaded each - epoch. - - Returns: - iterable, possible repeatable, yielding deserialized Python objects - """ - - def _iter_fn(): - with open(filename, "rb") as fd: - for line in fd: - blob = base64.b64decode(line) - if fraction and fraction < 1: - hash_float = bytes_to_float(blob) - if hash_float > fraction: - continue - example = pkl.loads(blob) - yield example - - return RepeatableIterator(_iter_fn) if repeatable else _iter_fn() diff --git a/jiant/utils/string_comparing.py b/jiant/utils/string_comparing.py new file mode 100644 index 000000000..4ba4e0af2 --- /dev/null +++ b/jiant/utils/string_comparing.py @@ -0,0 +1,47 @@ +import re +import string +import collections + + +def normalize_answer(s): + """Lower text and remove punctuation, articles and extra whitespace. + From official ReCoRD eval script + """ + + def remove_articles(text): + return re.sub(r"\b(a|an|the)\b", " ", text) + + def white_space_fix(text): + return " ".join(text.split()) + + def remove_punc(text): + exclude = set(string.punctuation) + return "".join(ch for ch in text if ch not in exclude) + + def lower(text): + return text.lower() + + return white_space_fix(remove_articles(remove_punc(lower(s)))) + + +def string_f1_score(prediction, ground_truth): + """Compute normalized token level F1 + From official ReCoRD eval script + """ + prediction_tokens = normalize_answer(prediction).split() + ground_truth_tokens = normalize_answer(ground_truth).split() + common = collections.Counter(prediction_tokens) & collections.Counter(ground_truth_tokens) + num_same = sum(common.values()) + if num_same == 0: + return 0 + precision = 1.0 * num_same / len(prediction_tokens) + recall = 1.0 * num_same / len(ground_truth_tokens) + f1 = (2 * precision * recall) / (precision + recall) + return f1 + + +def exact_match_score(prediction, ground_truth): + """Compute normalized exact match + From official ReCoRD eval script + """ + return normalize_answer(prediction) == normalize_answer(ground_truth) diff --git a/jiant/utils/testing/__init__.py b/jiant/utils/testing/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/jiant/utils/testing/tokenizer.py b/jiant/utils/testing/tokenizer.py new file mode 100644 index 000000000..743267c53 --- /dev/null +++ b/jiant/utils/testing/tokenizer.py @@ -0,0 +1,43 @@ +from typing import List + +from jiant.utils.python.datastructures import BiMap +from jiant.tasks.core import FeaturizationSpec + + +class SimpleSpaceTokenizer: + + pad_token = "" + cls_token = "" + sep_token = "" + unk_token = "" + SPECIAL_TOKENS = [pad_token, cls_token, sep_token, unk_token] + + def __init__(self, vocabulary: List[str], add_special=True): + if add_special: + vocabulary = self.SPECIAL_TOKENS + vocabulary + self.tokens_to_ids, self.ids_to_tokens = BiMap( + a=vocabulary, b=list(range(len(vocabulary))) + ).get_maps() + + def convert_tokens_to_ids(self, tokens: List[str]) -> List[int]: + return [self.tokens_to_ids[token] for token in tokens] + + def tokenize(self, string: str) -> List[str]: + return [ + token if token in self.tokens_to_ids else self.unk_token for token in string.split() + ] + + @classmethod + def get_feat_spec(cls, max_seq_length: int) -> FeaturizationSpec: + return FeaturizationSpec( + max_seq_length=max_seq_length, + cls_token_at_end=False, + pad_on_left=False, + cls_token_segment_id=0, + pad_token_segment_id=0, + pad_token_id=0, + pad_token_mask_id=0, + sequence_a_segment_id=0, + sequence_b_segment_id=1, + sep_token_extra=False, + ) diff --git a/jiant/utils/testing/utils.py b/jiant/utils/testing/utils.py new file mode 100644 index 000000000..fb17ed860 --- /dev/null +++ b/jiant/utils/testing/utils.py @@ -0,0 +1,5 @@ +import sys + + +def is_pytest(): + return "pytest" in sys.modules diff --git a/jiant/utils/tokenization_normalization.py b/jiant/utils/tokenization_normalization.py new file mode 100644 index 000000000..8a07be2c9 --- /dev/null +++ b/jiant/utils/tokenization_normalization.py @@ -0,0 +1,128 @@ +"""Tokenization normalization (to improve likelihood of good cross tokenization alignment). + +This module provides helpers for normalizing space tokenization and target tokenizations to make +proper alignment of the tokenizations more likely. + +Notes: + * Code is ported from https://github.com/nyu-mll/jiant/blob/master/jiant/utils/retokenize.py + +""" + +import re +import transformers +from typing import Sequence + +from jiant.utils.testing import utils as test_utils + + +def normalize_tokenizations( + space_tokenization: Sequence[str], + target_tokenization: Sequence[str], + tokenizer: transformers.PreTrainedTokenizer, +): + """Takes a space tokenization and a known target tokenization and normalizes them for alignment. + + The purpose of this function is to normalize the space-tokenized sequence and target + tokenization to make proper alignment of the tokenizations more likely. This includes adding + beginning of word (BoW) or end of word (EoW) tags to the space tokenized and/or target + tokenization sequences. This also includes removing tokenizer-specific meta symbols, and + lower casing characters in the space tokenization to match target tokenizers (if uncased). + + Warnings: + The normalized tokenizations produced by this function are not intended for use as inputs + to a model. These normalized tokenizations are only intended to be used to help find an + alignment between space tokenization and target tokenization. + + Args: + space_tokenization (Seqence[str]): space-tokenized token sequence. + target_tokenization (Seqence[str]): target tokenizer tokenized sequence. + tokenizer (PreTrainedTokenizer): tokenizer carrying info needed for target normalization. + + Returns: + Tuple(Sequence[str], Sequence[str]) of normalized space and target tokenizations. + + Raises: + ValueError: if either space or target tokenization is an empty sequence. + ValueError: if tokenizer does not have a normalization strategy in this function. + + """ + if len(space_tokenization) == 0 or len(target_tokenization) == 0: + raise ValueError("Empty token sequence.") + + if isinstance(tokenizer, transformers.BertTokenizer): + if tokenizer.init_kwargs.get("do_lower_case", False): + space_tokenization = [token.lower() for token in space_tokenization] + modifed_space_tokenization = bow_tag_tokens(space_tokenization) + modifed_target_tokenization = _process_wordpiece_tokens(target_tokenization) + elif isinstance(tokenizer, transformers.XLMTokenizer): + if tokenizer.init_kwargs.get("do_lowercase_and_remove_accent", False): + space_tokenization = [token.lower() for token in space_tokenization] + modifed_space_tokenization = eow_tag_tokens(space_tokenization) + modifed_target_tokenization = target_tokenization + elif isinstance(tokenizer, transformers.RobertaTokenizer): + modifed_space_tokenization = bow_tag_tokens(space_tokenization) + modifed_target_tokenization = ["Ġ" + target_tokenization[0]] + target_tokenization[1:] + modifed_target_tokenization = _process_bytebpe_tokens(modifed_target_tokenization) + elif isinstance(tokenizer, (transformers.AlbertTokenizer, transformers.XLMRobertaTokenizer)): + space_tokenization = [token.lower() for token in space_tokenization] + modifed_space_tokenization = bow_tag_tokens(space_tokenization) + modifed_target_tokenization = _process_sentencepiece_tokens(target_tokenization) + else: + if test_utils.is_pytest(): + from jiant.utils.testing.tokenizer import SimpleSpaceTokenizer + + if isinstance(tokenizer, SimpleSpaceTokenizer): + return space_tokenization, target_tokenization + raise ValueError("Tokenizer not supported.") + + # safety check: if normalization changed sequence length, alignment is likely to break. + assert len(modifed_space_tokenization) == len(space_tokenization) + assert len(modifed_target_tokenization) == len(target_tokenization) + + return modifed_space_tokenization, modifed_target_tokenization + + +def bow_tag_tokens(tokens: Sequence[str], bow_tag: str = ""): + """Applies a beginning of word (BoW) marker to every token in the tokens sequence.""" + return [bow_tag + t for t in tokens] + + +def eow_tag_tokens(tokens: Sequence[str], eow_tag: str = ""): + """Applies a end of word (EoW) marker to every token in the tokens sequence.""" + return [t + eow_tag for t in tokens] + + +def _process_wordpiece_tokens(tokens: Sequence[str]): + return [_process_wordpiece_token_for_alignment(token) for token in tokens] + + +def _process_sentencepiece_tokens(tokens: Sequence[str]): + return [_process_sentencepiece_token_for_alignment(token) for token in tokens] + + +def _process_bytebpe_tokens(tokens: Sequence[str]): + return [_process_bytebpe_token_for_alignment(token) for token in tokens] + + +def _process_wordpiece_token_for_alignment(t): + """Add word boundary markers, removes token prefix (no-space meta-symbol — '##' for BERT).""" + if t.startswith("##"): + return re.sub(r"^##", "", t) + else: + return "" + t + + +def _process_sentencepiece_token_for_alignment(t): + """Add word boundary markers, removes token prefix (space meta-symbol).""" + if t.startswith("▁"): + return "" + re.sub(r"^▁", "", t) + else: + return t + + +def _process_bytebpe_token_for_alignment(t): + """Add word boundary markers, removes token prefix (space meta-symbol).""" + if t.startswith("Ġ"): + return "" + re.sub(r"^Ġ", "", t) + else: + return t diff --git a/jiant/utils/tokenizers.py b/jiant/utils/tokenizers.py deleted file mode 100644 index d9c8fa0b8..000000000 --- a/jiant/utils/tokenizers.py +++ /dev/null @@ -1,179 +0,0 @@ -""" -Tokenizer class -To add a tokenizer, add to the below inherting from -main Tokenizer class. -""" -import functools -import logging as log -import os - -from sacremoses import MosesDetokenizer -from sacremoses import MosesTokenizer as SacreMosesTokenizer -from nltk.tokenize.simple import SpaceTokenizer -from jiant.huggingface_transformers_interface import input_module_uses_transformers -from transformers import ( - BertTokenizer, - RobertaTokenizer, - AlbertTokenizer, - XLNetTokenizer, - OpenAIGPTTokenizer, - GPT2Tokenizer, - TransfoXLTokenizer, - XLMTokenizer, -) - - -class Tokenizer(object): - def tokenize(self, sentence): - raise NotImplementedError - - -def select_tokenizer(args): - """ - Select a sane default tokenizer. - """ - if args.tokenizer == "auto": - if input_module_uses_transformers(args.input_module): - tokenizer_name = args.input_module - else: - tokenizer_name = "MosesTokenizer" - else: - tokenizer_name = args.tokenizer - return tokenizer_name - - -class SplitCharsTokenizer(Tokenizer): - """ - This tokenizer splits a string (sentence or word) into individual characters. - """ - - def __init__(self): - super().__init__() - - def tokenize(self, sequence): - return list(sequence) - - def detokenize(self, tokens): - return "".join(tokens) - - -class MosesTokenizer(Tokenizer): - def __init__(self): - super().__init__() - self._tokenizer = SacreMosesTokenizer() - self._detokenizer = MosesDetokenizer() - - def tokenize(self, sentence): - return self._tokenizer.tokenize(sentence) - - def detokenize(self, tokens): - """Unescape Moses punctuation tokens. - - Replaces escape sequences like [ with the original characters - (such as '['), so they better align to the original text. - """ - return [self._detokenizer.unescape_xml(t) for t in tokens] - - def detokenize_ptb(self, tokens): - # Not a perfect detokenizer, but a "good-enough" stand in. - rep_dict = { - "-LSB-": "[", - "-RSB-": "]", - "-LRB-": "(", - "-RRB-": ")", - "-LCB-": "{", - "-RCB-": "}", - "``": '"', - "''": '"', - } - str1 = self._detokenizer.detokenize(replace_list(tokens, rep_dict)) - return str1 - - -@functools.lru_cache(maxsize=8, typed=False) -def get_tokenizer(tokenizer_name): - log.info(f"\tLoading Tokenizer {tokenizer_name}") - if tokenizer_name.startswith("bert-"): - do_lower_case = tokenizer_name.endswith("uncased") - tokenizer = BertTokenizer.from_pretrained(tokenizer_name, do_lower_case=do_lower_case) - elif tokenizer_name.startswith("roberta-") or tokenizer_name.startswith("nyu-mll/roberta-"): - tokenizer = RobertaTokenizer.from_pretrained(tokenizer_name) - elif tokenizer_name.startswith("albert-"): - tokenizer = AlbertTokenizer.from_pretrained(tokenizer_name) - elif tokenizer_name.startswith("xlnet-"): - do_lower_case = tokenizer_name.endswith("uncased") - tokenizer = XLNetTokenizer.from_pretrained(tokenizer_name, do_lower_case=do_lower_case) - elif tokenizer_name.startswith("openai-gpt"): - tokenizer = OpenAIGPTTokenizer.from_pretrained(tokenizer_name) - elif tokenizer_name.startswith("gpt2"): - tokenizer = GPT2Tokenizer.from_pretrained(tokenizer_name) - elif tokenizer_name.startswith("transfo-xl-"): - # TransformerXL is trained on data pretokenized with MosesTokenizer - tokenizer = MosesTokenizer() - elif tokenizer_name.startswith("xlm-"): - tokenizer = XLMTokenizer.from_pretrained(tokenizer_name) - elif tokenizer_name == "MosesTokenizer": - tokenizer = MosesTokenizer() - elif tokenizer_name == "SplitChars": - tokenizer = SplitCharsTokenizer() - elif tokenizer_name == "": - tokenizer = SpaceTokenizer() - else: - tokenizer = None - return tokenizer - - -def bert_get_tokenized_string_span_map(text, b_tokens, verbose=False): - """ - Given a string, an a BERT tokenization of the string, returns list of - [ - bert_token, - start char index of token in string, - (exclusive) end char index of token in string, - ] - There is some fuzziness around assignment of spaces (particularly because of UNK tokens) - but the spans should be contiguous. - """ - b_token_char_indices = [] - text_i = 0 - for b_token in b_tokens: - stripped_b_token = b_token.replace("##", "") - if b_token == "[UNK]": - continue - - found_char_i = text[text_i:].find(stripped_b_token) - b_token_char_indices.append(text_i + found_char_i) - text_i += len(stripped_b_token) + found_char_i - b_token_char_indices.append(len(text)) - - result = [] - b_token_char_indices_i = -1 - end = 0 - for i, b_token in enumerate(b_tokens): - prev_end = end - - if b_token == "[UNK]": - start = prev_end - else: - b_token_char_indices_i += 1 - start = b_token_char_indices[b_token_char_indices_i] - - if i == len(b_tokens) - 1: - end = len(text) - elif b_token == "[UNK]": - end = b_token_char_indices[b_token_char_indices_i + 1] - elif b_token != "[UNK]" and b_tokens[i + 1] != "[UNK]": - end = b_token_char_indices[b_token_char_indices_i + 1] - elif b_tokens[i + 1] == "[UNK]": - end = start + len(b_token) - else: - raise RuntimeError() - - if verbose: - print(b_token, start, end, repr(text[start:end])) - result.append((b_token, start, end)) - return result - - -def replace_list(ls, d): - return [d.get(elem, elem) for elem in ls] diff --git a/jiant/utils/torch_utils.py b/jiant/utils/torch_utils.py new file mode 100644 index 000000000..98b7b65b0 --- /dev/null +++ b/jiant/utils/torch_utils.py @@ -0,0 +1,146 @@ +import copy +import math +import os + +import torch +import torch.nn as nn +import torch.nn.functional as F # noqa PyPep8Naming + +from torch.utils.data import Dataset, DataLoader + +CPU_DEVICE = torch.device("cpu") + + +def normalize_embedding_tensor(embedding): + return F.normalize(embedding, p=2, dim=1) + + +def embedding_norm_loss(raw_embedding): + norms = raw_embedding.norm(dim=1) + return F.mse_loss(norms, torch.ones_like(norms), reduction="none") + + +def get_val(x): + if isinstance(x, torch.Tensor): + return x.item() + else: + return x + + +def compute_pred_entropy(logits): + # logits are pre softmax + p = F.softmax(logits, dim=-1) + log_p = F.log_softmax(logits, dim=-1) + return -(p * log_p).sum(dim=-1).mean() + + +def compute_pred_entropy_clean(logits): + return float(compute_pred_entropy(logits).item()) + + +def copy_state_dict(state_dict, target_device=None): + copied_state_dict = copy.deepcopy(state_dict) + if target_device is None: + return copied_state_dict + else: + # Ensures that tensors with the same data_ptrs point to the same + # data_ptr after copying + new_state_dict = {} + unique_dict = {} + for k, v in copied_state_dict.items(): + unique_key = tuple(v.shape), v.data_ptr() + if unique_key not in unique_dict: + unique_dict[unique_key] = v.to(target_device) + # Create a view + new_state_dict[k] = unique_dict[unique_key][:] + + return new_state_dict + + +def get_parent_child_module_list(model): + ls = [] + for parent_name, parent_module in model.named_modules(): + for child_name, child_module in parent_module.named_children(): + ls.append((parent_name, parent_module, child_name, child_module)) + return ls + + +class IdentityModule(nn.Module): + # noinspection PyMethodMayBeStatic + def forward(self, *inputs): + if len(inputs) == 1: + return inputs[0] + else: + return inputs + + +def set_requires_grad(named_parameters, requires_grad): + for name, param in named_parameters: + set_requires_grad_single(param, requires_grad) + + +def set_requires_grad_single(param, requires_grad): + param.requires_grad = requires_grad + + +def get_only_requires_grad(parameters, requires_grad=True): + if isinstance(parameters, list): + if not parameters: + return [] + elif isinstance(parameters[0], tuple): + return [(n, p) for n, p in parameters if p.requires_grad == requires_grad] + else: + return [p for p in parameters if p.requires_grad == requires_grad] + elif isinstance(parameters, dict): + return {n: p for n, p in parameters if p.requires_grad == requires_grad} + else: + # TODO: Support generators (Issue #56) + raise RuntimeError("generators not yet supported") + + +class ListDataset(Dataset): + def __init__(self, data: list): + self.data = data + + def __len__(self): + return len(self.data) + + def __getitem__(self, item): + return self.data[item] + + +class DataLoaderWithLength(DataLoader): + def __len__(self): + # TODO: Revert after https://github.com/pytorch/pytorch/issues/36176 addressed (Issue #55) + # try: + # return super().__len__() + # except TypeError as e: + # try: + # return self.get_num_batches() + # except TypeError: + # pass + # raise e + return self.get_num_batches() + + def get_num_batches(self): + return math.ceil(len(self.dataset) / self.batch_size) + + +def is_data_parallel(torch_module): + return isinstance(torch_module, nn.DataParallel) + + +def safe_save(obj, path, temp_path=None): + if temp_path is None: + temp_path = path + "._temp" + torch.save(obj, temp_path) + if os.path.exists(path): + os.remove(path) + os.rename(temp_path, path) + + +def get_model_for_saving(model: nn.Module) -> nn.Module: + if isinstance(model, nn.DataParallel): + return model.module + else: + return model diff --git a/jiant/utils/transformer_utils.py b/jiant/utils/transformer_utils.py new file mode 100644 index 000000000..844b6c368 --- /dev/null +++ b/jiant/utils/transformer_utils.py @@ -0,0 +1,32 @@ +import contextlib + +from jiant.shared.model_resolution import ModelArchitectures + + +@contextlib.contextmanager +def output_hidden_states_context(encoder): + model_arch = ModelArchitectures.from_encoder(encoder) + if model_arch in ( + ModelArchitectures.BERT, + ModelArchitectures.ROBERTA, + ModelArchitectures.ALBERT, + ModelArchitectures.XLM_ROBERTA, + ModelArchitectures.ELECTRA, + ): + if hasattr(encoder.encoder, "output_hidden_states"): + # Transformers < v2 + modified_obj = encoder.encoder + elif hasattr(encoder.encoder.config, "output_hidden_states"): + # Transformers >= v3 + modified_obj = encoder.encoder.config + else: + raise RuntimeError(f"Failed to convert model {type(encoder)} to output hidden states") + old_value = modified_obj.output_hidden_states + modified_obj.output_hidden_states = True + yield + modified_obj.output_hidden_states = old_value + elif model_arch in (ModelArchitectures.BART, ModelArchitectures.MBART): + yield + return + else: + raise KeyError(model_arch) diff --git a/jiant/utils/utils.py b/jiant/utils/utils.py deleted file mode 100644 index f6b292e84..000000000 --- a/jiant/utils/utils.py +++ /dev/null @@ -1,498 +0,0 @@ -""" -Assorted utilities for working with neural networks in AllenNLP. -""" -import copy -import json -import logging -import os -from pkg_resources import resource_filename -from typing import Iterable, Sequence, Union -import glob -import torch -import jsondiff - -from allennlp.common.checks import ConfigurationError -from allennlp.common.params import Params -from sacremoses import MosesDetokenizer - -from .config import Params - -logger = logging.getLogger(__name__) # pylint: disable=invalid-name - -SOS_TOK, EOS_TOK = "", "" - -# Note: using the full 'detokenize()' method is not recommended, since it does -# a poor job of adding correct whitespace. Use unescape_xml() only. -_MOSES_DETOKENIZER = MosesDetokenizer() - - -def get_output_attribute(out, attribute_name, cuda_device, reduction="sum"): - """ - This function handles processing/reduction of output for both - DataParallel or non-DataParallel situations. - For the case of multiple GPUs, This function will - sum all values for a certain output attribute in various batches - together. - - Parameters - --------------------- - :param out: Dictionary, output of model during forward pass, - :param attribute_name: str, - :param cuda_device: list or int - :param reduction: (string, optional) reduction to apply to the output. Default: 'sum'. - """ - if isinstance(cuda_device, list): - if reduction == "sum": - return out[attribute_name].sum() - elif reduction == "mean": - return out[attribute_name].sum() / float(len(out[attribute_name])) - else: - raise ValueError("invalid reduction type argument") - else: - return out[attribute_name] - - -def get_model_attribute(model, attribute_name, cuda_device): - """ - Getter function for both CPU and GPU. - - Parameters - ____________________ - model: MultiTaskModel object, - attribute_name: str - - Returns - -------------------- - The attribute object from the model. - """ - # maybe we should do (int, list) - if isinstance(cuda_device, list): - return getattr(model.module, attribute_name) - else: - return getattr(model, attribute_name) - - -def select_pool_type(args): - """ - Select a sane default sequence pooling type. - """ - if args.pool_type == "auto": - pool_type = "max" - if args.sent_enc == "none": - if ( - args.input_module.startswith("bert-") - or args.input_module.startswith("roberta-") - or args.input_module.startswith("nyu-mll/roberta-") - or args.input_module.startswith("albert-") - or args.input_module.startswith("xlm-") - ): - pool_type = "first" - elif ( - args.input_module.startswith("xlnet-") - or args.input_module.startswith("openai-gpt") - or args.input_module.startswith("gpt2") - or args.input_module.startswith("transfo-xl-") - ): - pool_type = "final" - else: - pool_type = args.pool_type - return pool_type - - -def apply_standard_boundary_tokens(s1, s2=None): - """Apply and to sequences of string-valued tokens. - Corresponds to more complex functions used with models like XLNet and BERT. - """ - assert not s2, "apply_standard_boundary_tokens only supports single sequences" - return [SOS_TOK] + s1 + [EOS_TOK] - - -def check_for_previous_checkpoints(serialization_dir, tasks, phase, load_model): - """ - Check if there are previous checkpoints. - If phase == target_train, we loop through each of the tasks from last to first - to find the task with the most recent checkpoint. - If phase == pretrain, we check if there is a most recent checkpoint in the run - directory. - - Parameters - --------------------- - serialization_dir: str, - tasks: List of SamplingMultiTask objects, - phase: str - load_model: bool - - Returns - --------------------- - ckpt_directory: None or str, name of directory that checkpoints are in - with regards to the run directory. - val_pass: int, -1 if not found. - suffix: None or str, the suffix of the checkpoint. - """ - ckpt_directory = None - ckpt_epoch = -1 - ckpt_suffix = None - if phase == "target_train": - for task in tasks[::-1]: - val_pass, suffix = find_last_checkpoint_epoch(serialization_dir, phase, task.name) - # If we have found a task with a valid checkpoint for the first time. - if val_pass > -1 and ckpt_directory is None and phase == "target_train": - ckpt_directory = task.name - ckpt_epoch = val_pass - ckpt_suffix = suffix - else: - ckpt_epoch, ckpt_suffix = find_last_checkpoint_epoch(serialization_dir, phase, "") - if ckpt_epoch > -1: - # If there exists a pretraining checkpoint, set ckpt_directory. - ckpt_directory = "" - if ckpt_directory is not None: - assert_for_log( - load_model, - "There are existing checkpoints in %s which will be overwritten. " - "If you are restoring from a run, or would like to train from an " - "existing checkpoint, Use load_model = 1 to load the checkpoints instead. " - "If you don't want them, delete them or change your experiment name." - % serialization_dir, - ) - return ckpt_directory, ckpt_epoch, ckpt_suffix - - -def find_last_checkpoint_epoch(serialization_dir, search_phase="pretrain", task_name=""): - - """ - Search for the last epoch in a directory. - Here, we check that all four checkpoints (model, training_state, task_state, metrics) - exist and return the most recent epoch with all four checkpoints. - - """ - if not serialization_dir: - raise ConfigurationError( - "serialization_dir not specified - cannot restore a model without a directory path." - ) - suffix = None - max_val_pass = -1 - candidate_files = glob.glob( - os.path.join(serialization_dir, task_name, "*_state_{}_*".format(search_phase)) - ) - val_pass_to_files = {} - for x in candidate_files: - val_pass = int(x.split("_state_{}_val_".format(search_phase))[-1].split(".")[0]) - if not val_pass_to_files.get(val_pass): - val_pass_to_files[val_pass] = 0 - val_pass_to_files[val_pass] += 1 - if val_pass >= max_val_pass and val_pass_to_files[val_pass] == 4: - max_val_pass = val_pass - suffix = x - if suffix is not None: - suffix = suffix.split(serialization_dir)[-1] - suffix = "_".join(suffix.split("_")[1:]) - return max_val_pass, suffix - - -def copy_iter(elems): - """Simple iterator yielding copies of elements.""" - for elem in elems: - yield copy.deepcopy(elem) - - -def wrap_singleton_string(item: Union[Sequence, str]): - """ Wrap a single string as a list. """ - if isinstance(item, str): - # Can't check if iterable, because a string is an iterable of - # characters, which is not what we want. - return [item] - return item - - -def sort_param_recursive(data): - """ - Sorts the keys of a config.Params object in a param object recursively. - """ - import pyhocon - - if isinstance(data, dict) and not isinstance(data, pyhocon.ConfigTree): - for name, _ in list(data.items()): - data[name] = sort_param_recursive(data[name]) - else: - if isinstance(data, pyhocon.ConfigTree): - data = dict(sorted(data.items(), key=lambda x: x[0])) - return data - - -def parse_json_diff(diff): - """ - Parses the output of jsondiff's diff() function, which introduces - symbols such as replace. - The potential keys introduced are jsondiff.replace, jsondiff.insert, and jsondiff.delete. - For jsondiff.replace and jsondiff.insert, we simply want to return the - actual value of the replaced or inserted item, whereas for jsondiff.delete, we do not want to - show deletions in our parameters. - For example, for jsondiff.replace, the output of jsondiff may be the below: - {'mrpc': {replace: ConfigTree([('classifier_dropout', 0.1), ('classifier_hid_dim', 256), - ('max_vals', 8), ('val_interval', 1)])}} - since 'mrpc' was overriden in demo.conf. Thus, we only want to show the update and delete - the replace. The output of this function will be: - {'mrpc': ConfigTree([('classifier_dropout', 0.1), ('classifier_hid_dim', 256), - ('max_vals', 8), ('val_interval', 1)])} - See for more information on jsondiff. - """ - new_diff = {} - if isinstance(diff, dict): - for name, value in list(diff.items()): - - if name == jsondiff.replace or name == jsondiff.insert: - # get rid of the added jsondiff key - return value - - if name == jsondiff.delete: - del diff[name] - return None - - output = parse_json_diff(diff[name]) - if output: - diff[name] = output - return diff - - -def select_relevant_print_args(args): - """ - Selects relevant arguments to print out. - We select relevant arguments as the difference between defaults.conf and the experiment's - configuration. - - Params - ----------- - args: Params object - - Returns - ----------- - return_args: Params object with only relevant arguments - """ - import pyhocon - from pathlib import Path - - exp_config_file = os.path.join(args.run_dir, "params.conf") - root_directory = Path(__file__).parents[2] - defaults_file = resource_filename("jiant", "/config/defaults.conf") - exp_basedir = os.path.dirname(exp_config_file) - default_basedir = os.path.dirname(defaults_file) - fd = open(exp_config_file, "r") - exp_config_string = fd.read() - exp_config_string += "\n" - fd = open(defaults_file, "r") - default_config_string = fd.read() - default_config_string += "\n" - exp_config = dict( - pyhocon.ConfigFactory.parse_string(exp_config_string, basedir=exp_basedir).items() - ) - default_config = dict( - pyhocon.ConfigFactory.parse_string(default_config_string, basedir=default_basedir).items() - ) - sorted_exp_config = sort_param_recursive(exp_config) - sorted_defaults_config = sort_param_recursive(default_config) - diff_args = parse_json_diff(jsondiff.diff(sorted_defaults_config, sorted_exp_config)) - diff_args = Params.clone(diff_args) - result_args = select_task_specific_args(args, diff_args) - return result_args - - -def select_task_specific_args(exp_args, diff_args): - """ - A helper function that adds in task-specific parameters from the experiment - configurations for tasks in pretrain_tasks and target_tasks. - """ - exp_tasks = [] - if diff_args.get("pretrain_tasks"): - exp_tasks = diff_args.pretrain_tasks.split(",") - if diff_args.get("target_tasks"): - exp_tasks += diff_args.target_tasks.split(",") - if len(exp_tasks) == 0: - return diff_args - for key, value in list(exp_args.as_dict().items()): - stripped_key = key.replace("_", " ") - stripped_key = stripped_key.replace("-", " ") - param_task = None - # For each parameter, identify the task the parameter relates to (if any) - for task in exp_tasks: - if task in stripped_key and (("edges" in stripped_key) == ("edges" in task)): - # special logic for edges since there are edge versions of various - # tasks. - param_task = task - # Add parameters that pertain to the experiment tasks - if param_task and param_task in exp_tasks: - diff_args[key] = value - return diff_args - - -def load_model_state(model, state_path, gpu_id, skip_task_models=[], strict=True): - """ Helper function to load a model state - - Parameters - ---------- - model: The model object to populate with loaded parameters. - state_path: The path to a model_state checkpoint. - gpu_id: The GPU to use. -1 for no GPU. - skip_task_models: If set, skip task-specific parameters for these tasks. - This does not necessarily skip loading ELMo scalar weights, but I (Sam) sincerely - doubt that this matters. - strict: Whether we should fail if any parameters aren't found in the checkpoint. If false, - there is a risk of leaving some parameters in their randomly initialized state. - """ - model_state = torch.load(state_path) - - assert_for_log( - not (skip_task_models and strict), - "Can't skip task models while also strictly loading task models. Something is wrong.", - ) - for name, param in model.named_parameters(): - # Make sure no trainable params are missing. - if param.requires_grad: - if strict: - assert_for_log( - name in model_state, - "In strict mode and failed to find at least one parameter: " + name, - ) - elif (name not in model_state) and ((not skip_task_models) or ("_mdl" not in name)): - logging.error("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!") - logging.error("Parameter missing from checkpoint: " + name) - logging.error("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!") - - if skip_task_models: - keys_to_skip = [] - for task in skip_task_models: - new_keys_to_skip = [key for key in model_state if "%s_mdl" % task in key] - if new_keys_to_skip: - logging.info("Not loading task-specific parameters for task: %s" % task) - keys_to_skip += new_keys_to_skip - else: - logging.info("Found no task-specific parameters to skip for task: %s" % task) - for key in keys_to_skip: - del model_state[key] - - model.load_state_dict(model_state, strict=False) - logging.info("Loaded model state from %s", state_path) - - -def get_elmo_mixing_weights(text_field_embedder, task=None): - """ Get pre-softmaxed mixing weights for ELMo from text_field_embedder for a given task. - Stops program execution if something goes wrong (e.g. task is malformed, - resulting in KeyError). - - args: - - text_field_embedder (ElmoTextFieldEmbedder): the embedder used during the run - - task (Task): a Task object with a populated `_classifier_name` attribute. - - returns: - Dict[str, float]: dictionary with the values of each layer weight and of the scaling - factor. - """ - elmo = text_field_embedder.token_embedder_elmo._elmo - if task: - task_id = text_field_embedder.task_map[task._classifier_name] - else: - task_id = text_field_embedder.task_map["@pretrain@"] - task_weights = getattr(elmo, "scalar_mix_%d" % task_id) - params = { - "layer%d" % layer_id: p.item() - for layer_id, p in enumerate(task_weights.scalar_parameters.parameters()) - } - params["gamma"] = task_weights.gamma - return params - - -def format_output(obj, cuda_devices): - """ - Format output based on whether model is using DataParallel or not. - DataParallel necessitates objects to be gathered into GPU:0 to have - dimension 0. - This function will be used for scalar outputs of model forwards - such as loss and n_exs. - """ - if isinstance(cuda_devices, list): - if not isinstance(obj, torch.Tensor): - obj = torch.tensor(obj).cuda() - return obj.unsqueeze(0) - else: - return obj - - -def uses_cuda(cuda_devices): - return isinstance(cuda_devices, list) or (isinstance(cuda_devices, int) and cuda_devices >= 0) - - -def get_batch_size(batch, cuda_devices, keyword="input"): - """ Given a batch with unknown text_fields, get an estimate of batch size """ - if keyword == "input": - batch_field = batch["inputs"] if "inputs" in batch else batch["input1"] - else: - batch_field = batch[keyword] - keys = [k for k in batch_field.keys()] - batch_size = batch_field[keys[0]].size()[0] - return format_output(batch_size, cuda_devices) - - -def get_batch_utilization(batch_field, pad_idx=0): - """ Get ratio of batch elements that are padding - - Batch should be field, i.e. a dictionary of inputs""" - if "elmo" in batch_field: - idxs = batch_field["elmo"] - pad_ratio = idxs.eq(pad_idx).sum().item() / idxs.nelement() - else: - raise NotImplementedError - return 1 - pad_ratio - - -def maybe_make_dir(dirname): - """Make a directory if it doesn't exist.""" - os.makedirs(dirname, exist_ok=True) - - -def unescape_moses(moses_tokens): - """Unescape Moses punctuation tokens. - Replaces escape sequences like [ with the original characters - (such as '['), so they better align to the original text. - """ - return [_MOSES_DETOKENIZER.unescape_xml(t) for t in moses_tokens] - - -def load_json_data(filename: str) -> Iterable: - """ Load JSON records, one per line. """ - with open(filename, "r") as fd: - for line in fd: - yield json.loads(line) - - -def load_lines(filename: str) -> Iterable[str]: - """ Load text data, yielding each line. """ - with open(filename) as fd: - for line in fd: - yield line.strip() - - -def split_data(data, ratio, shuffle=1): - """Split dataset according to ratio, larger split is first return""" - n_exs = len(data[0]) - split_pt = int(n_exs * ratio) - splits = [[], []] - for col in data: - splits[0].append(col[:split_pt]) - splits[1].append(col[split_pt:]) - return tuple(splits[0]), tuple(splits[1]) - - -def assert_for_log(condition, error_message): - assert condition, error_message - - -def delete_all_checkpoints(serialization_dir): - common_checkpoints = glob.glob(os.path.join(serialization_dir, "*.th")) - task_checkpoints = glob.glob(os.path.join(serialization_dir, "*", "*.th")) - for file in common_checkpoints + task_checkpoints: - os.remove(file) - - -def transpose_list_of_lists(ls): - if len(ls) == 0: - return [] - return [[ls[i][j] for i in range(len(ls))] for j in range(len(ls[0]))] diff --git a/jiant/utils/zconf/__init__.py b/jiant/utils/zconf/__init__.py new file mode 100644 index 000000000..e81529288 --- /dev/null +++ b/jiant/utils/zconf/__init__.py @@ -0,0 +1,4 @@ +from .core import run_config, RunConfig, get_mode_and_cl_args, ModeLookupError +from .core import argparse_attr as attr + +__all__ = ("run_config", "RunConfig", "get_mode_and_cl_args", "ModeLookupError", "attr") diff --git a/jiant/utils/zconf/core.py b/jiant/utils/zconf/core.py new file mode 100644 index 000000000..68b0d3690 --- /dev/null +++ b/jiant/utils/zconf/core.py @@ -0,0 +1,318 @@ +import argparse +import attr +import copy as copylib +import inspect +import json +import shlex +import sys +import pathlib +from typing import Any, Tuple + +from jiant.utils.python.io import read_json +from jiant.utils.python.datastructures import combine_dicts + + +def _is_true(x): + return x == "True" + + +# noinspection PyShadowingBuiltins +def argparse_attr( + default=attr.NOTHING, + validator=None, + repr=True, + eq=None, + order=None, + hash=True, + init=True, + converter=None, + opt_string=None, + **argparse_kwargs, +): + if opt_string is None: + opt_string_ls = [] + elif isinstance(opt_string, str): + opt_string_ls = [opt_string] + else: + opt_string_ls = opt_string + + if argparse_kwargs.get("type", None) is bool: + argparse_kwargs["choices"] = {True, False} + argparse_kwargs["type"] = _is_true + + if argparse_kwargs.get("action", None) == "store_true": + default = False + + return attr.attr( + default=default, + validator=validator, + repr=repr, + eq=eq, + order=order, + hash=hash, + init=init, + converter=converter, + metadata={"opt_string_ls": opt_string_ls, "argparse_kwargs": argparse_kwargs}, + kw_only=True, + ) + + +def update_parser(parser, class_with_attributes: Any): + # TODO: Write more checks/tests for the parser creation in general (Issue #57) + for attribute in class_with_attributes.__attrs_attrs__: + if "argparse_kwargs" in attribute.metadata: + argparse_kwargs = attribute.metadata["argparse_kwargs"] + opt_string_ls = attribute.metadata["opt_string_ls"] + is_positional = "nargs" in argparse_kwargs + if not is_positional: + if attribute.default is attr.NOTHING: + argparse_kwargs = argparse_kwargs.copy() + argparse_kwargs["required"] = True + else: + argparse_kwargs["default"] = attribute.default + if is_positional: + argparse_arg_name = attribute.name + else: + argparse_arg_name = f"--{attribute.name}" + + parser.add_argument(argparse_arg_name, *opt_string_ls, **argparse_kwargs) + + +def read_parser(parser, class_with_attributes: Any, skip_non_class_attributes=None, args=None): + attribute_name_set = {attribute.name for attribute in class_with_attributes.__attrs_attrs__} + + kwargs = dict() + leftover_kwargs = dict() + + for k, v in vars(parser.parse_args(args)).items(): + if k in attribute_name_set: + kwargs[k] = v + else: + if skip_non_class_attributes is not None and k not in skip_non_class_attributes: + raise RuntimeError(f"Unknown attribute {k}") + leftover_kwargs[k] = v + + instance = class_with_attributes(**kwargs) + if skip_non_class_attributes: + return instance, leftover_kwargs + else: + return instance + + +# === Methods === # + +# == Class Methods +def run_cli(cls, args=None, prog=None, description=None): + parser = argparse.ArgumentParser(prog=prog, description=description) + update_parser( + parser=parser, class_with_attributes=cls, + ) + result = read_parser(parser=parser, class_with_attributes=cls, args=args) + assert isinstance(result, cls) + return result + + +def from_json(cls, json_string): + return cls(**json.loads(json_string)) + + +def from_json_path(cls, json_path): + with open(json_path, "r") as f: + return cls.from_json(f.read()) + + +def from_json_arg(cls): + assert len(sys.argv) == 2 + return cls.from_json_path(sys.argv[1]) + + +# == Instance Methods +def to_dict(self): + config_dict = {} + for attribute in inspect.getfullargspec(self.__class__).kwonlyargs: + config_dict[attribute] = getattr(self, attribute) + return config_dict + + +def to_json(self): + serialized_dict = self.to_dict() + for key, val in serialized_dict.items(): + if isinstance(val, pathlib.Path): + serialized_dict[key] = str(val) + return json.dumps(serialized_dict, indent=2) + + +def _inst_copy(self): + return copylib.deepcopy(self) + + +class RunConfig: + @classmethod + def run_cli(cls, prog=None, description=None): + parser = argparse.ArgumentParser(prog=prog, description=description) + return cls.run_from_parser(parser=parser) + + @classmethod + def run_from_parser(cls, parser): + update_parser( + parser=parser, class_with_attributes=cls, + ) + result = read_parser(parser=parser, class_with_attributes=cls) + assert isinstance(result, cls) + return result + + @classmethod + def get_attr_dict(cls): + # noinspection PyUnresolvedReferences + return {attr_.name: attr_ for attr_ in cls.__attrs_attrs__} + + @classmethod + def run_cli_json_prepend(cls, cl_args=None, prog=None, description=None): + # Prototype + # Assumptions: no positional? + parser = argparse.ArgumentParser(prog=prog, description=description) + result = cls.run_from_parser_json_prepend(parser=parser, cl_args=cl_args) + return result + + @classmethod + def run_from_parser_json_prepend(cls, parser, cl_args): + parser.add_argument("--ZZsrc", type=str, action="append") + parser.add_argument("--ZZoverrides", type=str, nargs="+") + pre_args, _ = parser.parse_known_args(cl_args) + if cl_args is None: + cl_args = sys.argv[1:] + if pre_args.ZZsrc is not None: + # Import configs from ZZsrc JSONs + imported_dict_ls = [read_json(path) for path in pre_args.ZZsrc] + combined_imported_dict = combine_dicts(imported_dict_ls, strict=True) + + # Record which args are going to be overridden + + if pre_args.ZZoverrides is not None: + raw_overrides = pre_args.ZZoverrides + overrides = [f"--{k}" for k in raw_overrides] + else: + raw_overrides = overrides = [] + + attr_dict = cls.get_attr_dict() + added_args = [] + for k, v in combined_imported_dict.items(): + formatted_k = f"--{k}" + # Ensure that args from imported, which are not specified to be overridden, + # aren't explicitly specified + if formatted_k in cl_args and formatted_k not in overrides: + raise RuntimeError(f"Attempting to override {formatted_k}") + + # Special handling for store_true args + if cls._is_store_true_arg(attr_dict[k]): + if v and k not in raw_overrides: + added_args.append(formatted_k) + else: + added_args.append(formatted_k) + added_args.append(str(v)) + submitted_args = added_args + cl_args + else: + assert pre_args.ZZoverrides is None + submitted_args = cl_args + update_parser( + parser=parser, class_with_attributes=cls, + ) + result, _ = read_parser( + parser=parser, + class_with_attributes=cls, + skip_non_class_attributes=["ZZsrc", "ZZoverrides"], + args=submitted_args, + ) + assert isinstance(result, cls) + return result + + @classmethod + def run_shlex_json_prepend(cls, string: str): + return cls.run_cli_json_prepend(cl_args=shlex.split(string.strip())) + + @classmethod + def default_run_cli(cls, cl_args=None, prog=None, description=None): + return cls.run_cli_json_prepend(cl_args=cl_args, prog=prog, description=description) + + @classmethod + def _is_store_true_arg(cls, attr_): + if "argparse_kwargs" not in attr_.metadata: + return False + if "action" not in attr_.metadata["argparse_kwargs"]: + return False + return attr_.metadata["argparse_kwargs"]["action"] == "store_true" + + @classmethod + def from_dict(cls, dictionary): + # noinspection PyArgumentList + return cls(**dictionary) + + @classmethod + def from_json(cls, json_string): + return cls.from_dict(json.loads(json_string)) + + @classmethod + def from_json_path(cls, json_path): + with open(json_path, "r") as f: + return cls.from_json(f.read()) + + @classmethod + def from_json_arg(cls): + assert len(sys.argv) == 2 + return cls.from_json_path(sys.argv[1]) + + def to_dict(self): + config_dict = {} + for attribute in inspect.getfullargspec(self.__class__).kwonlyargs: + config_dict[attribute] = getattr(self, attribute) + return config_dict + + def to_json(self): + serialized_dict = self.to_dict() + for key, val in serialized_dict.items(): + if isinstance(val, pathlib.Path): + serialized_dict[key] = str(val) + return json.dumps(serialized_dict, indent=2) + + def copy(self): + return copylib.deepcopy(self) + + def _post_init(self): + pass + + def __attrs_post_init__(self): + self._post_init() + + +# === Definition === # +def run_config(cls): + cls = attr.s(cls) + + if not isinstance(cls, RunConfig): + # Class methods + cls.run_cli = classmethod(run_cli) + cls.from_json = classmethod(from_json) + cls.from_json_path = classmethod(from_json_path) + cls.from_json_arg = classmethod(from_json_arg) + + # Instance methods + cls.to_dict = to_dict + cls.to_json = to_json + cls.copy = _inst_copy + + return cls + + +def get_sys_args(): + return sys.argv[1:] + + +def get_mode_and_cl_args(cl_args=None) -> Tuple[str, list]: + if cl_args is None: + cl_args = get_sys_args() + assert len(cl_args) >= 1, "First argument is the mode" + return cl_args[0], cl_args[1:] + + +class ModeLookupError(KeyError): + pass diff --git a/jiant/utils/zlog.py b/jiant/utils/zlog.py new file mode 100644 index 000000000..16b2ca5bc --- /dev/null +++ b/jiant/utils/zlog.py @@ -0,0 +1,227 @@ +import os +import time +import torch +import traceback + +from contextlib import contextmanager + +import jiant.utils.python.io as py_io +import jiant.utils.python.filesystem as filesystem + + +class BaseZLogger: + def log_context(self): + raise NotImplementedError() + + def write_entry(self, key, entry): + raise NotImplementedError() + + def write_obj(self, key, obj, entry): + raise NotImplementedError() + + def flush(self): + raise NotImplementedError() + + +class ZLogger(BaseZLogger): + def __init__(self, fol_path, log_errors=True, overwrite=False): + self.fol_path = fol_path + self.log_errors = log_errors + self.overwrite = overwrite + + self.write_mode = "w" if overwrite else "a" + os.makedirs(fol_path) + self.handles = {} + + @contextmanager + def log_context(self): + try: + yield self + except Exception: + if self.log_errors: + self.write_entry("errors", traceback.format_exc()) + raise + finally: + for f in self.handles.values(): + f.close() + + def write_entry(self, key, entry, do_print=False): + if isinstance(entry, dict): + entry = entry.copy() + else: + entry = {"data": entry} + entry["TIMESTAMP"] = time.time() + self._write_entry_to_file(key=key, entry=entry) + if do_print: + print(entry) + + def write_obj(self, key, obj, entry): + assert "DATA" not in entry + if isinstance(entry, dict): + entry = entry.copy() + else: + entry = {"data": entry} + time_stamp = time.time() + entry["DATA"] = self._save_obj(key, time_stamp, obj) + entry["TIMESTAMP"] = time_stamp + self._write_entry_to_file(key=key, entry=entry) + + def _save_obj(self, key, time_stamp, obj): + cache_path = self.get_cache_path(key) + os.makedirs(cache_path, exist_ok=True) + save_path = os.path.join(cache_path, str(time_stamp)) + torch.save(obj, save_path) + return save_path + + def check_handle_open(self, key): + if key in self.handles: + return + handle_path = self.get_path(key) + py_io.create_containing_folder(handle_path) + self.handles[key] = open(handle_path, self.write_mode) + + def get_path(self, key): + return os.path.join(self.fol_path, key + ".zlog") + + def get_cache_path(self, key): + return os.path.join(self.fol_path, key + "___CACHE") + + def flush(self, key=None): + if key is None: + for f in self.handles.values(): + f.flush() + elif isinstance(key, list): + for k in key: + self.handles[k].flush() + else: + self.handles[key].flush() + + def _write_entry_to_file(self, key, entry): + self.check_handle_open(key) + self.handles[key].write(py_io.to_jsonl(entry) + "\n") + + +class ZBufferedLogger(ZLogger): + def __init__( + self, + fol_path, + default_buffer_size=1, + buffer_size_dict=None, + log_errors=True, + overwrite=False, + ): + super().__init__(fol_path=fol_path, log_errors=log_errors, overwrite=overwrite) + self.default_buffer_size = default_buffer_size + self.buffer_size_dict = buffer_size_dict.copy() if buffer_size_dict else {} + self.buffer_dict = {} + + def check_handle_open(self, key): + super().check_handle_open(key=key) + if key not in self.buffer_dict: + self.buffer_dict[key] = [] + if key not in self.buffer_size_dict: + self.buffer_size_dict[key] = self.default_buffer_size + + def _write_entry_to_file(self, key, entry): + self.check_handle_open(key) + self.buffer_dict[key].append(entry) + if len(self.buffer_dict[key]) >= self.buffer_size_dict[key]: + self.flush(key) + + def _write_buffer(self, key): + if not self.buffer_dict[key]: + return + self.handles[key].write( + "".join(py_io.to_jsonl(entry) + "\n" for entry in self.buffer_dict[key]) + ) + self.buffer_dict[key] = [] + + def flush(self, key=None): + if key is None: + for k, f in self.handles.items(): + self._write_buffer(k) + f.flush() + elif isinstance(key, list): + for k in key: + self._write_buffer(k) + self.handles[k].flush() + else: + self._write_buffer(key) + self.handles[key].flush() + + +class _VoidZLogger(BaseZLogger): + def log_context(self): + yield + + def write_entry(self, key, entry): + pass + + def write_obj(self, key, obj, entry): + pass + + def flush(self): + pass + + +class _PrintZLogger(BaseZLogger): + def log_context(self): + yield + + def write_entry(self, key, entry): + print(f"{key}: {entry}") + + def write_obj(self, key, obj, entry): + print(f"{key}: {obj}") + + def flush(self): + pass + + +class InMemoryZLogger(BaseZLogger): + def __init__(self): + self.entries = {} + self.data = {} + + def log_context(self): + yield + + def write_entry(self, key, entry): + if isinstance(entry, dict): + entry = entry.copy() + else: + entry = {"data": entry} + entry["TIMESTAMP"] = time.time() + self._write_entry(key=key, entry=entry) + + def write_obj(self, key, obj, entry): + assert "DATA" not in entry + if isinstance(entry, dict): + entry = entry.copy() + else: + entry = {"data": entry} + time_stamp = time.time() + entry["DATA"] = obj + entry["TIMESTAMP"] = time_stamp + self._write_entry(key=key, entry=entry) + + def _write_entry(self, key, entry): + if key not in self.entries: + self.entries[key] = [] + self.entries[key].append(entry) + + def flush(self): + pass + + +VOID_LOGGER = _VoidZLogger() +PRINT_LOGGER = _PrintZLogger() + + +def load_log(fol_path): + all_paths = filesystem.find_files_with_ext(fol_path, "zlog") + log_data = {} + for path in all_paths: + key = os.path.abspath(path).replace(os.path.abspath(fol_path), "")[1:].replace(".zlog", "") + log_data[key] = py_io.read_jsonl(path) + return log_data diff --git a/main.py b/main.py deleted file mode 100644 index 0d8815204..000000000 --- a/main.py +++ /dev/null @@ -1,29 +0,0 @@ -import logging as log - -log.basicConfig( - format="%(asctime)s: %(message)s", datefmt="%m/%d %I:%M:%S %p", level=log.INFO -) # noqa - -import sys - -from jiant.__main__ import main - -# Global notification handler, can be accessed outside main() during exception handling. -EMAIL_NOTIFIER = None - -if __name__ == "__main__": - try: - main(sys.argv[1:]) - if EMAIL_NOTIFIER is not None: - EMAIL_NOTIFIER(body="Run completed successfully!", prefix="") - except BaseException as e: - # Make sure we log the trace for any crashes before exiting. - log.exception("Fatal error in main():") - if EMAIL_NOTIFIER is not None: - import traceback - - tb_lines = traceback.format_exception(*sys.exc_info()) - EMAIL_NOTIFIER(body="".join(tb_lines), prefix="FAILED") - raise e # re-raise exception, in case debugger is attached. - sys.exit(1) - sys.exit(0) diff --git a/probing/README.md b/probing/README.md deleted file mode 100644 index 5783441b3..000000000 --- a/probing/README.md +++ /dev/null @@ -1,201 +0,0 @@ -# Edge Probing - -This is the main page for the following papers: - -- **What do you learn from context? Probing for sentence structure in contextualized word representations** (Tenney et al., ICLR 2019), the "edge probing paper": [[paper](https://openreview.net/forum?id=SJzSgnRcKX)] [[poster](https://iftenney.github.io/edgeprobe-poster-iclr-final.pdf)] -- **BERT Rediscovers the Classical NLP Pipeline** (Tenney et al., ACL 2019), the "BERT layer paper":[[paper](https://arxiv.org/abs/1905.05950)] [[poster](https://iftenney.github.io/bert-layer-poster-acl-final.pdf)] - -Most of the code for these is integrated into `jiant` proper, but this directory contains data preparation and analysis code specific to the edge probing experiments. Additionally, the runner scripts live in [jiant/scripts/edgeprobing](../scripts/edgeprobing). - -## Getting Started - -First, follow the set-up instructions for `jiant`: [Getting Started](../README.md#getting-started). Be sure you set all the required environment variables, and that you download the git submodules. - -If you want to run GloVe or CoVe experiments, also be sure to set `WORD_EMBS_FILE` to point to a copy of [`glove.840B.300d.txt`](http://nlp.stanford.edu/data/glove.840B.300d.zip). - -Next, download and process the edge probing data. You'll need access to the underlying corpora, in particular OntoNotes 5.0 and a processed (JSON) copy of the SPR1 dataset. Edit the paths in [get_and_process_all_data.sh](get_and_process_all_data.sh) to point to these resources, then run: - -```sh -mkdir -p $JIANT_DATA_DIR -./get_and_process_all_data.sh $JIANT_DATA_DIR -``` -This should populate `$JIANT_DATA_DIR/edges` with directories for each task, each containing a number of `.json` files as well as `labels.txt`. For more details on the data format, see below. - -The main entry point for edge probing is [`jiant/main.py`](../main.py). The main arguments are a config file and any parameter overrides. The [`jiant/jiant/config/edgeprobe/`](../jiant/config/edgeprobe/) folder contains [HOCON](https://github.com/lightbend/config/blob/master/HOCON.md) files as a starting point for all the edge probing experiments. - -For a quick test run, use a small dataset like `spr2` and a small encoder like CoVe: -```sh -cd ${PWD%/jiant*}/jiant -python main.py --config_file jiant/config/edgeprobe/edgeprobe_cove.conf \ - -o "target_tasks=edges-spr2,exp_name=ep_cove_demo" -``` -This will keep the encoder fixed and train an edge probing classifier on the SPR2 dataset. It should run in about 4 minutes on a K80 GPU. It'll produce an output directory in `$JIANT_PROJECT_PREFIX/ep_cove_demo`. There's a lot of stuff in here, but the files of interest are: -``` -vocab/ - tokens.txt # token vocab used by the encoder - edges-spr2_labels.txt # label vocab used by the probing classifier -run/ - tensorboard/ # tensorboard logdir - edges-spr2_val.json # dev set predictions, in edge probing JSON format - edges-spr2_test.json # test set predictions, in edge probing JSON format - log.log # training and eval log file (human-readable text) - params.conf # serialized parameter list - edges-spr2/model_state_eval_*.best.th # PyTorch saved checkpoint -``` -`jiant` uses [tensorboardX](https://github.com/lanpa/tensorboardX) to record loss curves and a few other metrics during training. You can view with: -``` -tensorboard --logdir $JIANT_PROJECT_PREFIX/ep_cove_demo/run/tensorboard -``` - -You can use the `run/*_val.json` and `run/*_test.json` files to run scoring and analysis. There are some helper utilities which allow you to load and aggregate predictions across multiple runs. In particular: -- [analysis.py](analysis.py) contains utilities to load predictions into a set - of DataFrames, as well as to pretty-print edge probing examples. -- [edgeprobe_preds_sandbox.ipynb](edgeprobe_preds_sandbox.ipynb) walks through - some of the features in `analysis.py` -- [analyze_runs.py](analyze_runs.py) is a helper script to process a set of - predictions into a condensed `.tsv` format. It computes confusion matricies for each label and along various stratifiers (like span distance) so you can easily and quickly perform further aggregation and compute metrics like accuracy, precision, recall, and F1. In particular, the `run`, `task`, `label`, `stratifier` (optional), and `stratum_key` (optional) columns serve as identifiers, and the confusion matrix is stored in four columns: `tp_count`, `fp_count`, `tn_count`, and `tp_count`. If you want to aggregate over a group of labels (like SRL core roles), just sum the `*_count` columns for that group before computing metrics. -- [get_scalar_mix.py](get_scalar_mix.py) is a helper script to extract scalar - mixing weights and export to `.tsv`. -- [analysis_edgeprobe_standard.ipynb](analysis_edgeprobe_standard.ipynb) shows - some example analysis on the output of `analyze_runs.py` and `get_scalar_mix.py`. This mostly does shallow processing over the output, but the main idiosyncracies to know are: for `coref-ontonotes`, use the `1` label instead of `_micro_avg_`, and for `srl-ontonotes` we report a `_clean_micro_` metric which aggregates all the labels that don't start with `R-` or `C-`. - -## Running the experiments from the paper - -We provide a frozen branch, [`ep_frozen_20190723`](https://github.com/nyu-mll/jiant/tree/ep_frozen_20190723), which should reproduce the experiments from both papers above. - -Additionally, there's an older branch, [`edgeprobe_frozen_feb2019`](https://github.com/jsalt18-sentence-repl/jiant/tree/edgeprobe_frozen_feb2019), which is a snapshot of `jiant` as of the final version of the ICLR paper. However, this is much messier than above. - -The configs in `jiant/jiant/config/edgeprobe/edgeprobe_*.conf` are the starting point for the experiments in the paper, but are supplemented by a number of parameter overrides (the `-o` flag to `main.py`). We use a set of bash functions to keep track of these, which are maintained in [`jiant/scripts/edges/exp_fns.sh`](../scripts/edges/exp_fns.sh). - -To run a standard experiment, you can do something like: -```sh -pushd ${PWD%/jiant*}/jiant -source scripts/edges/exp_fns.sh -bert_mix_exp edges-srl-ontonotes bert-base-uncased -``` - -The paper (Table 2 in particular) represents the output of a large number of experiments. Some of these are quite fast (lexical baselines and CoVe), and some are quite slow (GPT model, syntax tasks with lots of targets). We use a Kubernetes cluster running on Google Cloud Platform (GCP) to manage all of these. For more on Kubernetes, see [`jiant/gcp/kubernetes`](../gcp/kubernetes). - -The master script for the experiments is [`jiant/scripts/edgeprobing/kubernetes_run_all.sh`](../scripts/edgeprobing/kubernetes_run_all.sh). Mostly, all this does is set up some paths and submit pods to run on the cluster. If you want to run the same set of experiments in a different environment, you can copy that script and modify the `kuberun()` function to submit a job or to simply run locally. - -There's also an analysis helper script, [jiant/scripts/edgeprobing/analyze_project.sh](../scripts/edgeprobing/analyze_project.sh), which runs `analyze_runs.py` and `get_scalar_mix.py` on the output of a set of Kubernetes runs. Note that scoring runs is CPU-intensive and might take a while for larger experiments. - -There are two analysis notebooks which produce the main tables and figures for each paper. These are frozen as-is for a reference, but probably won't be runnable directly as they reference a number of specific data paths: -- [analysis_edgeprobe_ICLR_camera_ready.ipynb](analysis_edgeprobe_ICLR_camera_ready.ipynb) -- [analysis_bertlayer_ACL_camera_ready.ipynb](analysis_bertlayer_ACL_camera_ready.ipynb) - -**Note on coreference metrics:** the default model actually trains on two mutually-exclusive targets with labels "`0`" and "`1`". In the papers we ignore the "`0`" class and report F1 scores from treating the positive ("`1`") class as a binary target. See [this issue](https://github.com/nyu-mll/jiant/issues/1084#issuecomment-622633655) for more detail, or Ctrl+F for `is_coref_task` in the above notebooks for the relevant code. - -If you hit any snags (_Editor's note: it's research code, you probably will_), contact Ian (email address in the paper) for help. - -## Edge Probing Utilities - -This directory contains a number of utilities for the edge probing project. - -In particular: -- [edge_data_stats.py](edge_data_stats.py) prints stats, like the number of - tokens, number of spans, and number of labels. -- [get_edge_data_labels.py](get_edge_data_labels.py) compiles a list of all the - unique labels found in a dataset. -- [retokenize_edge_data.py](retokenize_edge_data.py) applies tokenizers (MosesTokenizer, OpenAI.BPE, or a BERT wordpiece model) and re-map spans to the new tokenization. -- [convert_edge_data_to_tfrecord.py](convert_edge_data_to_tfrecord.py) converts - edge probing JSON data to TensorFlow examples. - -The [data/](data/) subdirectory contains scripts to download each probing dataset and convert it to the edge probing JSON format, described below. - -If you just want to get all the data, see [get_and_process_all_data.sh](get_and_process_all_data.sh); this is a convenience wrapper over the instructions in [data/README.md](data/README.md). - -## Data Format - -The edge probing data is stored and manipulated as JSON (or the equivalent Python dict) which encodes a single `text` field and a number of `targets` each consisting of `span1`, (optionally) `span2`, and a list of `labels`. The `info` field can be used for additional metadata. See examples below: - -**SRL example** -```js -// span1 is predicate, span2 is argument -{ - “text”: “Ian ate strawberry ice cream”, - “targets”: [ - { “span1”: [1,2], “span2”: [0,1], “label”: “A0” }, - { “span1”: [1,2], “span2”: [2,5], “label”: “A1” } - ], - “info”: { “source”: “PropBank”, ... } -} -``` - -**Constituents example** -```js -// span2 is unused -{ - “text”: “Ian ate strawberry ice cream”, - “targets”: [ - { “span1”: [0,1], “label”: “NNP” }, - { “span1”: [1,2], “label”: “VBD” }, - ... - { “span1”: [2,5], “label”: “NP” } - { “span1”: [1,5], “label”: “VP” } - { “span1”: [0,5], “label”: “S” } - ] - “info”: { “source”: “PTB”, ... } -} -``` - -**Semantic Proto-roles (SPR) example** -```js -// span1 is predicate, span2 is argument -// label is a list of attributes (multilabel) -{ - 'text': "The main reason is Google is more accessible to the global community and you can rest assured that it 's not going to go away ." - 'targets': [ - { - 'span1': [3, 4], 'span2': [0, 3], - 'label': ['existed_after', 'existed_before', 'existed_during', - 'instigation', 'was_used'], - 'info': { ... } - }, - ... - ] - 'info': {'source': 'SPR2', ... }, -} -``` - -## Labels and Retokenization - -For each task, we need to perform two additional preprocessing steps before training using main.py. - -First, extract the set of available labels: -``` -export TASK_DIR="$JIANT_DATA_DIR/edges/" -python jiant/probing/get_edge_data_labels.py -o $TASK_DIR/labels.txt \ - -i $TASK_DIR/*.json -s -``` - -Second, make retokenized versions for any tokenizers you need. For example: -```sh -# for CoVe and GPT, respectively -python jiant/probing/retokenize_edge_data.py -t "MosesTokenizer" $TASK_DIR/*.json -python jiant/probing/retokenize_edge_data.py -t "OpenAI.BPE" $TASK_DIR/*.json -# for BERT -python jiant/probing/retokenize_edge_data.py -t "bert-base-uncased" $TASK_DIR/*.json -python jiant/probing/retokenize_edge_data.py -t "bert-large-uncased" $TASK_DIR/*.json -``` - -This will save retokenized versions alongside the original files. - -## Data Statistics - -Appendix B of the edge probing paper is wrong in several entries. This table contains the exact counts for the number of examples, tokens, and targets (train/dev/test) for each task. - -| Task | Labels | Examples | Tokens | Total Targets | -| ---- |:------:|:--------:|:------:|:-------:| -| Part-of-Speech | 48 |115812/15680/12217 | 2200865/304701/230118 | 2070382/290013/212121 | -| Constituents | 30 |115812/15680/12217 | 2200865/304701/230118 | 1851590/255133/190535 | -| Dependencies | 49 |12522/2000/2075 | 203919/25110/25049 | 203919/25110/25049 | -| Entites | 18 |115812/15680/12217 | 2200865/304701/230118 | 128738/20354/12586 | -| SRL (all) | 66 |253070/35297/26715 | 6619740/934744/711746 | 598983/83362/61716 | -| _Core roles_ | 6 |253070/35297/26715 | 6619740/934744/711746 | 411469/57237/41735 | -| _Non-core roles_ | 21 |253070/35297/26715 | 6619740/934744/711746 | 170220/23754/18290 | -| OntoNotes coref. | 2 |115812/15680/12217 | 2200865/304701/230118 | 207830/26333/27800 | -| SPR1 | 18 |3843/518/551 | 81255/10692/11955 | 7611/1071/1055 | -| SPR2 | 20 |2226/291/276 | 46969/5592/4929 | 4925/630/582 | -| Winograd coref. | 2 |958/223/518 | 14384/4331/7952 | 1787/379/949 | -| Rel. (SemEval) | 19 |6851/1149/2717 | 117232/20361/46873 | 6851/1149/2717 | diff --git a/probing/analysis.py b/probing/analysis.py deleted file mode 100644 index 37811a7e6..000000000 --- a/probing/analysis.py +++ /dev/null @@ -1,931 +0,0 @@ -## -# Helper libraries for #datascience on Edge-Probing data. - -import collections -import io -import itertools -import json -import logging as log -import os -import re -import sys - -from allennlp.data import Vocabulary -from bokeh import palettes -from sklearn import metrics -import numpy as np -import pandas as pd - -from jiant.utils import utils - -from typing import Dict, Iterable, List, Tuple - -## -# Task list for stable ordering, and human-friendly display names. -TASK_TO_DISPLAY_NAME = collections.OrderedDict( - [ - ("pos-ontonotes", "Part-of-Speech"), - ("nonterminal-ontonotes", "Constituents"), - ("dep-labeling-ewt", "Dependencies"), # old task name - ("dep-ud-ewt", "Dependencies"), - ("ner-ontonotes", "Entities"), - ("srl-conll2012", "SRL"), # old task name - ("srl-ontonotes", "SRL"), - ("coref-ontonotes-conll", "OntoNotes Coref."), # old task name - ("coref-ontonotes", "OntoNotes Coref."), - ("spr1", "SPR1"), - ("spr2", "SPR2"), - ("dpr", "Winograd Coref."), - ("rel-semeval", "Relations (SemEval)"), - ] -) -TASKS = list(TASK_TO_DISPLAY_NAME.keys()) - - -def task_sort_key(candidate): - """Generate a stable sort key for a task, with optional suffixes.""" - for i, name in enumerate(TASKS): - if candidate.startswith(name): - return (i, candidate) - return (len(TASKS), candidate) - - -def clean_task_name(task_name): - """Return a cleaned version of a jiant task name.""" - c1 = re.sub(r"^edges-", "", task_name) - c2 = re.sub(r"-openai$", "", c1) # legacy, for old -openai versions of tasks - return c2 - - -def make_display_name(task, label=None): - display_task = TASK_TO_DISPLAY_NAME[task] - if label in {"_micro_avg_", "1", None}: - return display_task - elif label == "_clean_micro_": - return f"{display_task} (all)" - elif label == "_core_": - return f"{display_task} (core)" - elif label == "_non_core_": - return f"{display_task} (non-core)" - else: - clean_label = label.strip("_") - return f"{display_task} ({clean_label})" - - -# See https://bokeh.pydata.org/en/latest/docs/reference/palettes.html -_clist = palettes.Category20[20] -# Experiment type list for stable ordering -# These correspond to the convention in scripts/edges/exp_fns.sh -# and scripts/edges/kubernetes_run_all.sh for naming experiments. -exp_types_clist_idx = [ - ("glove", 2), # orange - ("cove", 6), # deep red - ("elmo-chars", 18), # aqua - ("elmo-ortho", 8), # purple - ("elmo-full", 0), # blue - ("openai-lex", 16), # olive - ("openai-cat", 4), # green - ("openai-mix", 12), # pink - ("openai", 4), # green - ("openai-bwb", 12), # pink - ("train-chars", 10), # brown -] -# Add BERT experiments; all the same colors. -for bert_name in ["base-uncased", "base-cased", "large-uncased", "large-cased"]: - exp_types_clist_idx.append((f"bert-{bert_name}-lex", 16)) # olive - exp_types_clist_idx.append((f"bert-{bert_name}-cat", 4)) # green - exp_types_clist_idx.append((f"bert-{bert_name}-mix", 12)) # pink - exp_types_clist_idx.append((f"bert-{bert_name}-at", 6)) # deep red - -exp_types_colored = collections.OrderedDict() -# Use lighter versions for base model, darker for CNN -for k, v in exp_types_clist_idx: - exp_types_colored[k] = _clist[v + 1] - exp_types_colored[k + "-cnn1"] = _clist[v] - exp_types_colored[k + "-cnn2"] = _clist[v] - -EXP_TYPES, EXP_PALETTE = zip(*exp_types_colored.items()) - - -def exp_type_sort_key(candidate): - """Generate a stable sort key for an experiment type, with optional suffixes.""" - exp_type = candidate.split(" ", 1)[0] - m = re.match(r"(.*)-\d+$", exp_type) - if m: - exp_type = m.group(1) - return (EXP_TYPES.index(exp_type), candidate) - - -def _parse_exp_name(exp_name): - m = re.match(r"([a-z-]+)([-_](\d+))?-edges-([a-z-]+)", exp_name) - assert m is not None, f"Unable to parse run name: {exp_name}" - prefix, _, num, task = m.groups() - return prefix, num, task - - -def get_exp_type(exp_name): - return _parse_exp_name(exp_name)[0] - - -def get_layer_num(exp_name): - return _parse_exp_name(exp_name)[1] - - -## -# Predicates for filtering and aggregation - - -def is_core_role(label): - return re.match(r"^ARG[0-5A]$", label) is not None - - -def is_non_core_role(label): - return re.match(r"^ARGM(-.+)?$", label) is not None - - -def is_core_or_noncore(label): - return is_core_role(label) or is_non_core_role(label) - - -def is_srl_task(task): - return task.startswith("srl-") - - -def is_coref_task(task): - return task.startswith("coref-") - - -def is_relation_task(task): - return task.startswith("rel-") - - -def is_positive_relation(label): - return (not label.startswith("_")) and (label != "no_relation") and (label != "Other") - - -def spans_intersect(a, b): - if a[0] <= b[0] and b[0] < a[1]: - return True - if b[0] <= a[0] and a[0] < b[1]: - return True - return False - - -## -# Scoring helpers - - -def harmonic_mean(a, b): - return 2 * a * b / (a + b) - - -def score_from_confusion_matrix(df): - """Score a DataFrame in-place, computing metrics for each row based on confusion matricies.""" - assert "tn_count" in df.columns # true negatives - assert "fp_count" in df.columns # false positives - assert "fn_count" in df.columns # false negatives - assert "tp_count" in df.columns # true negatives - - df["pred_pos_count"] = df.tp_count + df.fp_count - df["true_pos_count"] = df.tp_count + df.fn_count - df["total_count"] = df.tp_count + df.tn_count + df.fp_count + df.fn_count - - # NOTE: this overwrites any _macro_avg_ rows by recomputing the micro-average! - df["accuracy"] = (df.tp_count + df.tn_count) / df.total_count - df["precision"] = df.tp_count / df.pred_pos_count - df["recall"] = df.tp_count / df.true_pos_count - df["f1_score"] = harmonic_mean(df.precision, df.recall).fillna(0) - - # Approximate error intervals using normal approximation - # https://en.wikipedia.org/wiki/Binomial_proportion_confidence_interval#Wilson_score_interval - z = 1.96 # 95% confidence - df["accuracy_errn95"] = z * (df.accuracy * (1 - df.accuracy) / df.total_count).map(np.sqrt) - df["precision_errn95"] = z * (df.precision * (1 - df.precision) / df.pred_pos_count).map( - np.sqrt - ) - df["recall_errn95"] = z * (df.recall * (1 - df.recall) / df.true_pos_count).map(np.sqrt) - # This probably isn't the right way to combine for F1 score, but should be - # a reasonable estimate. - df["f1_errn95"] = harmonic_mean(df.precision_errn95, df.recall_errn95) - - -## -# Old scoring helpers (TODO: remove these) -def get_precision(df): - return df.tp_count / (df.tp_count + df.fp_count) - - -def get_recall(df): - return df.tp_count / (df.tp_count + df.fn_count) - - -def get_f1(df): - return 2 * df.precision * df.recall / (df.precision + df.recall) - - -def _get_nested_vals(record, outer_key): - return {f"{outer_key}.{key}": value for key, value in record.get(outer_key, {}).items()} - - -def _expand_runs(seq, nreps): - """Repeat each element N times, consecutively. - - i.e. _expand_runs([1,2,3], 4) -> [1,1,1,1,2,2,2,2,3,3,3,3] - """ - return np.tile(seq, (nreps, 1)).T.flatten() - - -class EdgeProbingExample(object): - """Wrapper object to handle an edge probing example. - - Mostly exists for pretty-printing, but could be worth integrating - into the data-handling code. - """ - - def __init__(self, record: Dict, label_vocab: List[str] = None, pred_thresh: float = 0.5): - """Construct an example from a record. - - Record should be derived from the standard JSON format. - """ - self._data = record - self._label_vocab = label_vocab - self._pred_thresh = pred_thresh - - @staticmethod - def format_span(tokens, s, e, max_tok=None, render_fn=lambda tokens: " ".join(tokens)): - selected_tokens = tokens[s:e] - if max_tok is not None and len(selected_tokens) > max_tok: - selected_tokens = selected_tokens[:max_tok] + ["..."] - return '[{:2d},{:2d})\t"{:s}"'.format(s, e, render_fn(selected_tokens)) - - def _fmt_preds(self, preds): - buf = io.StringIO() - for i, p in enumerate(preds["proba"]): - if p < self._pred_thresh: - continue - buf.write(" {:5s} ".format("" if buf.getvalue() else "pred:")) - label = self._label_vocab[i] if self._label_vocab else str(i) - buf.write(f"\t\t {label:s} ({p:.2f})\n") - return buf.getvalue() - - def __str__(self): - buf = io.StringIO() - text = self._data["text"] - tokens = text.split() - buf.write("Text ({:d}): {:s}\n".format(len(tokens), text)) - - for t in self._data["targets"]: - buf.write("\n") - buf.write(" span1: {}\n".format(self.format_span(tokens, *t["span1"]))) - if "span2" in t: - buf.write(" span2: {}\n".format(self.format_span(tokens, *t["span2"]))) - labels = utils.wrap_singleton_string(t["label"]) - buf.write(" label: ({:d})\t\t {}\n".format(len(labels), ", ".join(labels))) - # Show predictions, if present. - if "preds" in t: - buf.write(self._fmt_preds(t["preds"])) - - return buf.getvalue() - - def __repr__(self): - return "EdgeProbingExample(" + repr(self._data) + ")" - - -class Predictions(object): - """Container class to manage a set of predictions from the Edge Probing - model. Recommended usage: - - preds = analysis.Predictions.from_run("/path/to/exp/run", - "edges-srl-conll2005", - "val") - - # preds has the following fields: - preds.vocab # allennlp.data.Vocabulary object - preds.example_df # DataFrame of example info (sentence text) - preds.target_df # DataFrame of target info (spans, labels, - # predicted scores, etc.) - - """ - - def _split_and_flatten_records(self, records: Iterable[Dict]): - ex_records = [] # long-form example records, minus targets - tr_records = [] # long-form target records with 'idx' column - for idx, r in enumerate(records): - d = {"text": r["text"], "idx": idx} - d.update(_get_nested_vals(r, "info")) - d.update(_get_nested_vals(r, "preds")) - ex_records.append(d) - - for t in r["targets"]: - d = {"label": utils.wrap_singleton_string(t["label"]), "idx": idx} - if "span1" in t: - d["span1"] = tuple(t["span1"]) - if "span2" in t: - d["span2"] = tuple(t["span2"]) - d.update(_get_nested_vals(t, "info")) - d.update(_get_nested_vals(t, "preds")) - tr_records.append(d) - return ex_records, tr_records - - def _labels_to_ids(self, labels: List[str]) -> List[int]: - return [self.vocab.get_token_index(l, namespace=self.label_namespace) for l in labels] - - def _get_num_labels(self) -> int: - return self.vocab.get_vocab_size(namespace=self.label_namespace) - - def _label_ids_to_khot(self, label_ids: List[int]) -> np.ndarray: - arr = np.zeros(self._get_num_labels(), dtype=np.int32) - arr[label_ids] = 1 - return arr - - def _get_label(self, i: int) -> str: - return self.vocab.get_token_from_index(i, namespace=self.label_namespace) - - def __init__(self, vocab: Vocabulary, records: Iterable[Dict], label_namespace=None): - self.vocab = vocab - self.label_namespace = label_namespace - self.all_labels = [self._get_label(i) for i in range(self._get_num_labels())] - - ex_records, tr_records = self._split_and_flatten_records(records) - self.example_df = pd.DataFrame.from_records(ex_records) - self.example_df.set_index("idx", inplace=True, drop=False) - self.target_df = pd.DataFrame.from_records(tr_records) - - # Apply indexing to labels - self.target_df["label.ids"] = self.target_df["label"].map(self._labels_to_ids) - # Convert labels to k-hot to align to predictions - self.target_df["label.khot"] = self.target_df["label.ids"].map(self._label_ids_to_khot) - - # Placeholders, will compute later if requested. - # Use non-underscore versions to access via propert getters. - self._target_df_wide = None # wide-form targets (expanded) - self._target_df_long = None # long-form targets (melted by label) - - def _make_wide_target_df(self): - log.info("Generating wide-form target DataFrame. May be slow... ") - # Expand labels to columns - expanded_y_true = self.target_df["label.khot"].apply(pd.Series) - expanded_y_true.columns = ["label.true." + l for l in self.all_labels] - expanded_y_pred = self.target_df["preds.proba"].apply(pd.Series) - expanded_y_pred.columns = ["preds.proba." + l for l in self.all_labels] - wide_df = pd.concat([self.target_df, expanded_y_true, expanded_y_pred], axis="columns") - DROP_COLS = ["preds.proba", "label", "label.ids", "label.khot"] - wide_df.drop(labels=DROP_COLS, axis=1, inplace=True) - log.info("Done!") - return wide_df - - @property - def target_df_wide(self): - """Target df in wide form. Compute only if requested.""" - if self._target_df_wide is None: - self._target_df_wide = self._make_wide_target_df() - return self._target_df_wide - - def _make_long_target_df(self): - df = self.target_df - log.info("Generating long-form target DataFrame. May be slow... ") - num_targets = len(df) - # Index into self.example_df for text. - ex_idxs = _expand_runs(df["idx"], len(self.all_labels)) - # Index into self.target_df for other metadata. - idxs = _expand_runs(df.index, len(self.all_labels)) - # Repeat labels for each target. - labels = np.tile(self.all_labels, num_targets) - # Flatten lists using numpy - *much* faster than using Pandas. - label_true = np.array(df["label.khot"].tolist(), dtype=np.int32).flatten() - preds_proba = np.array(df["preds.proba"].tolist(), dtype=np.float32).flatten() - assert len(label_true) == len(preds_proba) - assert len(label_true) == len(labels) - d = { - "idx": idxs, - "label": labels, - "label.true": label_true, - "preds.proba": preds_proba, - "ex_idx": ex_idxs, - } - # Repeat some metadata fields if available. - # Use these for stratified scoring. - if "info.height" in df.columns: - log.info("info.height field detected; copying to long-form " "DataFrame.") - d["info.height"] = _expand_runs(df["info.height"], len(self.all_labels)) - if "span2" in df.columns: - log.info("span2 detected; adding span_distance to long-form " "DataFrame.") - - def _get_midpoint(span): - return (span[1] - 1 + span[0]) / 2.0 - - def span_sep(a, b): - ma = _get_midpoint(a) - mb = _get_midpoint(b) - if mb >= ma: # b starts later - return max(0, b[0] - a[1]) - else: # a starts later - return max(0, a[0] - b[1]) - - span_distance = [span_sep(a, b) for a, b in zip(df["span1"], df["span2"])] - d["span_distance"] = _expand_runs(span_distance, len(self.all_labels)) - # Reconstruct a DataFrame. - long_df = pd.DataFrame(d) - log.info("Done!") - return long_df - - @property - def target_df_long(self): - """Target df in long form (one row per label, per target). - Compute only if requested. - """ - if self._target_df_long is None: - self._target_df_long = self._make_long_target_df() - return self._target_df_long - - @staticmethod - def score_long_df(df: pd.DataFrame) -> Dict[str, float]: - """Compute metrics for a single DataFrame of long-form predictions.""" - # Confusion matrix; can compute other metrics from this later. - y_true = df["label.true"] - y_pred = df["preds.proba"] >= 0.5 - C = metrics.confusion_matrix(y_true, y_pred, labels=[0, 1]) - tn, fp, fn, tp = C.ravel() - record = dict() - record["tn_count"] = tn - record["fp_count"] = fp - record["fn_count"] = fn - record["tp_count"] = tp - return record - - def score_by_label(self) -> pd.DataFrame: - """Compute metrics for each label, and in the aggregate.""" - long_df = self.target_df_long - gb = long_df.groupby(by=["label"]) - records = [] - for label, idxs in gb.groups.items(): - sub_df = long_df.loc[idxs] - record = self.score_long_df(sub_df) - record["label"] = label - records.append(record) - score_df = pd.DataFrame.from_records(records) - ## - # Compute macro average - agg_map = {} - for col in score_df.columns: - # TODO(ian): ths _score_ entries don't actually do anything, - # since when run the DataFrame only contains '_counts' columns. - if col.endswith("_score"): - agg_map[col] = "mean" - elif col.endswith("_count"): - agg_map[col] = "sum" - elif col == "label": - pass - else: - log.warning("Unsupported column '%s'", col) - macro_avg = score_df.agg(agg_map) - macro_avg["label"] = "_macro_avg_" - score_df = score_df.append(macro_avg, ignore_index=True) - - ## - # Compute micro average - micro_avg = pd.Series(self.score_long_df(long_df)) - micro_avg["label"] = "_micro_avg_" - score_df = score_df.append(micro_avg, ignore_index=True) - - ## - # Compute stratified scores by special fields - for field in ["info.height", "span_distance"]: - if field not in long_df.columns: - continue - log.info( - "Found special field '%s' with %d unique values.", - field, - len(long_df[field].unique()), - ) - gb = long_df.groupby(by=[field]) - records = [] - for key, idxs in gb.groups.items(): - sub_df = long_df.loc[idxs] - record = self.score_long_df(sub_df) - record["label"] = "_{:s}_{:s}_".format(field, str(key)) - record["stratifier"] = field - record["stratum_key"] = key - records.append(record) - score_df = score_df.append( - pd.DataFrame.from_records(records), ignore_index=True, sort=False - ) - - ## - # Move "label" column to the beginning. - cols = list(score_df.columns) - cols.insert(0, cols.pop(cols.index("label"))) - score_df = score_df.reindex(columns=cols) - return score_df - - @classmethod - def from_run(cls, run_dir: str, task_name: str, split_name: str): - # Load vocabulary - exp_dir = os.path.dirname(run_dir.rstrip("/")) - vocab_path = os.path.join(exp_dir, "vocab") - log.info("Loading vocabulary from %s" % vocab_path) - vocab = Vocabulary.from_files(vocab_path) - label_namespace = f"{task_name}_labels" - - # Load predictions - preds_file = os.path.join(run_dir, f"{task_name}_{split_name}.json") - log.info("Loading predictions from %s" % preds_file) - return cls(vocab, utils.load_json_data(preds_file), label_namespace=label_namespace) - - -class Comparison(object): - """Container class to represent a pair of experiments.""" - - def __init__(self, base: Predictions, expt: Predictions, label_filter=lambda label: True): - assert len(base.all_labels) == len(expt.all_labels) - assert len(base.example_df) == len(expt.example_df) - assert len(base.target_df) == len(expt.target_df) - - self.base = base - self.expt = expt - - # Score & compare - log.info("Scoring base run...") - self.base_scores = base.score_by_label() - self.base_scores["run"] = "base" - log.info("Scoring expt run...") - self.expt_scores = expt.score_by_label() - self.expt_scores["run"] = "expt" - log.info("Done scoring!") - - _mask = self.base_scores["label"].map(label_filter) - self.base_scores = self.base_scores[_mask] - _mask = self.expt_scores["label"].map(label_filter) - self.expt_scores = self.expt_scores[_mask] - - self.long_scores = pd.concat([self.base_scores, self.expt_scores]) - # Wide-form scores for direct comparison - df = pd.merge( - self.base_scores, - self.expt_scores, - on=["label", "true_count"], - suffixes=("_base", "_expt"), - ) - df["abs_diff_f1"] = df["f1_score_expt"] - df["f1_score_base"] - # Compute relative error reduction - df["rel_diff_f1"] = df["abs_diff_f1"] / (1 - df["f1_score_base"]) - # Net diffs, computed from accuracy - df["net_diffs"] = ( - np.abs(df["acc_score_expt"] - df["acc_score_base"]) * len(base.target_df) - ).astype(np.int32) - df["base_headroom"] = ((1 - df["acc_score_base"]) * len(base.target_df)).astype(np.int32) - df["expt_headroom"] = ((1 - df["acc_score_expt"]) * len(expt.target_df)).astype(np.int32) - self.wide_scores = df - - def plot_scores( - self, - task_name, - metric="f1", - sort_field="expt_headroom", - sort_ascending=False, - row_height=400, - palette=None, - ): - import bokeh - import bokeh.plotting as bp - - _SCORE_COL = f"{metric:s}_score" - _ABS_DIFF_COL = f"abs_diff_{metric:s}" - _REL_DIFF_COL = f"rel_diff_{metric:s}" - - # Long-form data, for paired bar chart. - # TODO: switch to using wide-form for all? - long_df = self.long_scores.copy() - long_df["row_key"] = list(zip(long_df["label"], long_df["run"])) - long_df["fmt_score"] = long_df[_SCORE_COL].map(lambda s: "{:.02f}".format(s)) - long_ds = bokeh.models.ColumnDataSource(data=long_df) - - # Wide-form data, for counts & comparison metrics. - wide_df = self.wide_scores.copy() - wide_df["_diff_label_offset"] = 10 * np.sign(wide_df[_ABS_DIFF_COL]) - wide_df["_count_diff_offset"] = -1.25 * wide_df["_diff_label_offset"] - - # Formatting label text - wide_df["_net_diff_count_label_text"] = wide_df["net_diffs"].map( - lambda s: "~ {:d} ex".format(s) if s else "" - ) - wide_df["_abs_diff_label_text"] = wide_df[_ABS_DIFF_COL].map(lambda s: "{:.02f}".format(s)) - wide_df["_rel_diff_label_text"] = wide_df[_REL_DIFF_COL].map( - lambda s: "({:.02f})".format(s) if s else "" - ) - wide_ds = bokeh.models.ColumnDataSource(data=wide_df) - - # Prepare shared categorical axis - runs = sorted(long_df["run"].unique()) - labels = wide_df.sort_values(by=sort_field, ascending=sort_ascending)["label"] - categories = list(itertools.product(labels, runs)) - - if not palette: - # palette = bokeh.palettes.Spectral6 - # palette = bokeh.palettes.Category10[len(runs)] - palette = bokeh.palettes.Category20[len(runs)] - # palette = bokeh.palettes.Set2[len(runs)] - fill_cmap = bokeh.transform.factor_cmap("run", palette, runs) - width = 35 * len(categories) - tools = "xwheel_zoom,xwheel_pan,xpan,save,reset" - - # Top plot: score bars - factor_range = bokeh.models.FactorRange( - *categories, range_padding=0.5, range_padding_units="absolute" - ) - p1 = bp.figure( - title=f"Performance by label ({task_name})", - x_range=factor_range, - y_range=[0, 1], - width=width, - height=row_height, - tools=tools, - ) - p1.vbar( - x="row_key", - top=_SCORE_COL, - width=0.95, - fill_color=fill_cmap, - line_color=None, - source=long_ds, - ) - label_kw = dict( - text_align="right", - text_baseline="middle", - y_offset=-3, - text_font_size="11pt", - angle=90, - angle_units="deg", - ) - score_labels = bokeh.models.LabelSet( - x="row_key", y=_SCORE_COL, text="fmt_score", source=long_ds, **label_kw - ) - p1.add_layout(score_labels) - p1.xaxis.major_label_orientation = 1 - p1.yaxis.bounds = (0, 1) - - # Second plot: absolute diffs - p2 = bp.figure( - title=f"Absolute and (Relative) diffs by label ({task_name})", - x_range=p1.x_range, - width=width, - height=row_height, - tools=tools, - ) - p2.vbar( - x="label", - top="rel_diff_f1", - width=1.90, - fill_color="DarkRed", - fill_alpha=0.20, - line_color=None, - source=wide_ds, - ) - p2.vbar( - x="label", - top="abs_diff_f1", - width=1.90, - fill_color="DarkRed", - line_color=None, - source=wide_ds, - ) - label_kw = dict( - text_align="center", - text_baseline="middle", - y_offset="_diff_label_offset", - source=wide_ds, - ) - delta_labels = bokeh.models.LabelSet( - x="label", y="abs_diff_f1", text="_abs_diff_label_text", **label_kw - ) - p2.add_layout(delta_labels) - rel_labels = bokeh.models.LabelSet( - x="label", y="rel_diff_f1", text="_rel_diff_label_text", **label_kw - ) - p2.add_layout(rel_labels) - count_labels = bokeh.models.LabelSet( - x="label", - y=0, - y_offset="_count_diff_offset", - text="_net_diff_count_label_text", - text_align="center", - text_baseline="middle", - text_font_style="italic", - text_color="gray", - text_font_size="10pt", - source=wide_ds, - ) - p2.add_layout(count_labels) - - p2.y_range.start = -1.10 - p2.y_range.end = 1.10 - p2.yaxis.bounds = (-1, 1) - # Hacky: Hide category labels, not needed on this plot. - p2.xaxis.major_label_text_color = None - p2.xaxis.major_label_text_font_size = "0pt" - p2.xaxis.major_tick_line_color = None - - # Bottom plot: count bars - p3 = bp.figure( - title=f"Counts by label ({task_name})", - x_range=p1.x_range, - width=width, - height=row_height, - tools=tools, - ) - p3.vbar( - x="label", - top="true_count", - width=1.90, - fill_color="orange", - line_color=None, - source=wide_ds, - ) - label_kw = dict(text_align="center", text_baseline="top", y_offset=-5) - count_labels = bokeh.models.LabelSet( - x="label", y="true_count", text="true_count", source=wide_ds, **label_kw - ) - p3.add_layout(count_labels) - p3.y_range.flipped = True - p3.y_range.end = 0 - p3.y_range.range_padding = 0.20 - # Hacky: Hide category labels, not needed on this plot. - p3.xaxis.major_label_text_color = None - p3.xaxis.major_label_text_font_size = "0pt" - p3.xaxis.major_tick_line_color = None - - # Fix labels for SPR case, labels are long - if max(map(len, labels)) > 10: - # Top plot: rotate labels, add height. - p1.xaxis.group_label_orientation = np.pi / 2 - p1.plot_height += 150 - # Middle plot: hide labels. - p2.xaxis.group_text_color = None - p2.xaxis.group_text_font_size = "0pt" - # Bottom plot: rotate labels, add height. - p3.xaxis.group_label_orientation = np.pi / 2 - p3.plot_height += 75 - - # Create plot layout. - plots = bokeh.layouts.gridplot( - [p1, p2, p3], ncols=1, toolbar_location="left", merge_tools=True, sizing_mode="fixed" - ) - header = bokeh.models.Div(text=f"

{task_name} sorted by '{sort_field}'

", width=600) - return bokeh.layouts.column(header, plots) - - -class MultiComparison(object): - """Similar to Comparison, but handles more than 2 experiments. - - Renders grouped bar plot and count bars, but not diff plot. - """ - - def __init__(self, runs_by_name: collections.OrderedDict, label_filter=lambda label: True): - num_labels = {k: len(v.all_labels) for k, v in runs_by_name.items()} - assert len(set(num_labels.values())) == 1 - num_examples = {k: len(v.example_df) for k, v in runs_by_name.items()} - assert len(set(num_examples.values())) == 1 - num_targets = {k: len(v.target_df) for k, v in runs_by_name.items()} - assert len(set(num_targets.values())) == 1 - - self.runs_by_name = runs_by_name - - self.scores_by_name = collections.OrderedDict() - for name, run in self.runs_by_name.items(): - log.info("Scoring run '%s'" % name) - score_df = run.score_by_label() - score_df["run"] = name - _mask = score_df["label"].map(label_filter) - score_df = score_df[_mask] - self.scores_by_name[name] = score_df - - log.info("Done scoring!") - - self.long_scores = pd.concat(self.scores_by_name.values()) - - def plot_scores( - self, - task_name, - metric="f1", - sort_field="expt_headroom", - sort_run=None, - sort_ascending=False, - row_height=400, - cmap=None, - ): - import bokeh - import bokeh.plotting as bp - - _SCORE_COL = f"{metric:s}_score" - - # Long-form data, for grouped bar chart. - long_df = self.long_scores.copy() - long_df["row_key"] = list(zip(long_df["label"], long_df["run"])) - long_df["fmt_score"] = long_df[_SCORE_COL].map(lambda s: "{:.02f}".format(s)) - long_ds = bokeh.models.ColumnDataSource(data=long_df) - - # Single scored run, for plotting counts. - sort_run = sort_run or list(self.scores_by_name.keys())[0] - wide_df = self.scores_by_name[sort_run] - wide_ds = bokeh.models.ColumnDataSource(data=wide_df) - - # Prepare shared categorical axis - # runs = sorted(long_df['run'].unique()) - runs = list(self.scores_by_name.keys()) - labels = wide_df.sort_values(by=sort_field, ascending=sort_ascending)["label"] - # labels = sorted(long_df['label'].unique()) - categories = list(itertools.product(labels, runs)) - - if cmap: - palette = [cmap[name] for name in runs] - else: - # palette = bokeh.palettes.Spectral6 - # palette = bokeh.palettes.Category10[len(runs)] - palette = bokeh.palettes.Category20[len(runs)] - # palette = bokeh.palettes.Set2[len(runs)] - fill_cmap = bokeh.transform.factor_cmap("run", palette, runs) - width = 30 * len(categories) + 10 * len(self.scores_by_name) - tools = "xwheel_zoom,xwheel_pan,xpan,save,reset" - - # Top plot: score bars - factor_range = bokeh.models.FactorRange( - *categories, range_padding=0.5, range_padding_units="absolute" - ) - p1 = bp.figure( - title=f"Performance by label ({task_name})", - x_range=factor_range, - y_range=[0, 1], - width=width, - height=row_height, - tools=tools, - ) - p1.vbar( - x="row_key", - top=_SCORE_COL, - width=0.95, - fill_color=fill_cmap, - line_color=None, - source=long_ds, - ) - label_kw = dict( - text_align="right", - text_baseline="middle", - y_offset=-3, - text_font_size="11pt", - angle=90, - angle_units="deg", - ) - score_labels = bokeh.models.LabelSet( - x="row_key", y=_SCORE_COL, text="fmt_score", source=long_ds, **label_kw - ) - p1.add_layout(score_labels) - p1.xaxis.major_label_orientation = 1 - p1.yaxis.bounds = (0, 1) - - # Middle plot: doesn't make sense for n > 2 experiments. - - # Bottom plot: count bars - p3 = bp.figure( - title=f"Counts by label ({task_name})", - x_range=p1.x_range, - width=width, - height=row_height, - tools=tools, - ) - p3.vbar( - x="label", - top="true_count", - width=1.90, - fill_color="orange", - line_color=None, - source=wide_ds, - ) - label_kw = dict(text_align="center", text_baseline="top", y_offset=-5) - count_labels = bokeh.models.LabelSet( - x="label", y="true_count", text="true_count", source=wide_ds, **label_kw - ) - p3.add_layout(count_labels) - p3.y_range.flipped = True - p3.y_range.end = 0 - p3.y_range.range_padding = 0.20 - # Hacky: Hide category labels, not needed on this plot. - p3.xaxis.major_label_text_color = None - p3.xaxis.major_label_text_font_size = "0pt" - p3.xaxis.major_tick_line_color = None - - # Fix labels for SPR case, labels are long - if max(map(len, labels)) > 10: - # Top plot: rotate labels, add height. - p1.xaxis.group_label_orientation = np.pi / 2 - p1.plot_height += 150 - # Bottom plot: rotate labels, add height. - p3.xaxis.group_label_orientation = np.pi / 2 - p3.plot_height += 75 - - # Create plot layout. - plots = bokeh.layouts.gridplot( - [p1, p3], ncols=1, toolbar_location="left", merge_tools=True, sizing_mode="fixed" - ) - header_txt = f"{task_name}, sorted by '{sort_run}.{sort_field}'" - header = bokeh.models.Div(text=f"

{header_txt}

", width=600) - return bokeh.layouts.column(header, plots) diff --git a/probing/analysis_bertlayer_ACL_camera_ready.ipynb b/probing/analysis_bertlayer_ACL_camera_ready.ipynb deleted file mode 100644 index 70a6e7675..000000000 --- a/probing/analysis_bertlayer_ACL_camera_ready.ipynb +++ /dev/null @@ -1,8156 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Edgeprobe Aggregate Analysis (for ACL camera-ready)\n", - "\n", - "This is the main analysis notebook for [BERT Rediscovers the Classical NLP Pipeline\n", - "](https://arxiv.org/abs/1905.05950), a.k.a. \"the BERT layer paper\", which makes the aggregate plots (Figure 1 and 2).\n", - "\n", - "This notebook is intended to be run on the output of the [`analyze_runs.py`](analyze_runs.py) script; run that on a folder of experiments to produce a `scores.tsv` file that can be loaded here." - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Better speed can be achieved with apex installed from https://www.github.com/nvidia/apex.\n" - ] - } - ], - "source": [ - "import sys, os, re, json\n", - "from importlib import reload\n", - "import itertools\n", - "import collections\n", - "\n", - "import numpy as np\n", - "import pandas as pd\n", - "\n", - "import analysis\n", - "reload(analysis)\n", - "\n", - "tasks = analysis.TASKS\n", - "exp_types = analysis.EXP_TYPES\n", - "\n", - "task_sort_key = analysis.task_sort_key\n", - "exp_type_sort_key = analysis.exp_type_sort_key\n", - "\n", - "from scipy.special import logsumexp\n", - "from scipy.stats import entropy\n", - "\n", - "def softmax(x, axis=None):\n", - " return np.exp(x - logsumexp(x, axis=axis, keepdims=True))" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - "
\n", - " \n", - " Loading BokehJS ...\n", - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": [ - "\n", - "(function(root) {\n", - " function now() {\n", - " return new Date();\n", - " }\n", - "\n", - " var force = true;\n", - "\n", - " if (typeof (root._bokeh_onload_callbacks) === \"undefined\" || force === true) {\n", - " root._bokeh_onload_callbacks = [];\n", - " root._bokeh_is_loading = undefined;\n", - " }\n", - "\n", - " var JS_MIME_TYPE = 'application/javascript';\n", - " var HTML_MIME_TYPE = 'text/html';\n", - " var EXEC_MIME_TYPE = 'application/vnd.bokehjs_exec.v0+json';\n", - " var CLASS_NAME = 'output_bokeh rendered_html';\n", - "\n", - " /**\n", - " * Render data to the DOM node\n", - " */\n", - " function render(props, node) {\n", - " var script = document.createElement(\"script\");\n", - " node.appendChild(script);\n", - " }\n", - "\n", - " /**\n", - " * Handle when an output is cleared or removed\n", - " */\n", - " function handleClearOutput(event, handle) {\n", - " var cell = handle.cell;\n", - "\n", - " var id = cell.output_area._bokeh_element_id;\n", - " var server_id = cell.output_area._bokeh_server_id;\n", - " // Clean up Bokeh references\n", - " if (id != null && id in Bokeh.index) {\n", - " Bokeh.index[id].model.document.clear();\n", - " delete Bokeh.index[id];\n", - " }\n", - "\n", - " if (server_id !== undefined) {\n", - " // Clean up Bokeh references\n", - " var cmd = \"from bokeh.io.state import curstate; print(curstate().uuid_to_server['\" + server_id + \"'].get_sessions()[0].document.roots[0]._id)\";\n", - " cell.notebook.kernel.execute(cmd, {\n", - " iopub: {\n", - " output: function(msg) {\n", - " var id = msg.content.text.trim();\n", - " if (id in Bokeh.index) {\n", - " Bokeh.index[id].model.document.clear();\n", - " delete Bokeh.index[id];\n", - " }\n", - " }\n", - " }\n", - " });\n", - " // Destroy server and session\n", - " var cmd = \"import bokeh.io.notebook as ion; ion.destroy_server('\" + server_id + \"')\";\n", - " cell.notebook.kernel.execute(cmd);\n", - " }\n", - " }\n", - "\n", - " /**\n", - " * Handle when a new output is added\n", - " */\n", - " function handleAddOutput(event, handle) {\n", - " var output_area = handle.output_area;\n", - " var output = handle.output;\n", - "\n", - " // limit handleAddOutput to display_data with EXEC_MIME_TYPE content only\n", - " if ((output.output_type != \"display_data\") || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n", - " return\n", - " }\n", - "\n", - " var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n", - "\n", - " if (output.metadata[EXEC_MIME_TYPE][\"id\"] !== undefined) {\n", - " toinsert[toinsert.length - 1].firstChild.textContent = output.data[JS_MIME_TYPE];\n", - " // store reference to embed id on output_area\n", - " output_area._bokeh_element_id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n", - " }\n", - " if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n", - " var bk_div = document.createElement(\"div\");\n", - " bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n", - " var script_attrs = bk_div.children[0].attributes;\n", - " for (var i = 0; i < script_attrs.length; i++) {\n", - " toinsert[toinsert.length - 1].firstChild.setAttribute(script_attrs[i].name, script_attrs[i].value);\n", - " }\n", - " // store reference to server id on output_area\n", - " output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n", - " }\n", - " }\n", - "\n", - " function register_renderer(events, OutputArea) {\n", - "\n", - " function append_mime(data, metadata, element) {\n", - " // create a DOM node to render to\n", - " var toinsert = this.create_output_subarea(\n", - " metadata,\n", - " CLASS_NAME,\n", - " EXEC_MIME_TYPE\n", - " );\n", - " this.keyboard_manager.register_events(toinsert);\n", - " // Render to node\n", - " var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n", - " render(props, toinsert[toinsert.length - 1]);\n", - " element.append(toinsert);\n", - " return toinsert\n", - " }\n", - "\n", - " /* Handle when an output is cleared or removed */\n", - " events.on('clear_output.CodeCell', handleClearOutput);\n", - " events.on('delete.Cell', handleClearOutput);\n", - "\n", - " /* Handle when a new output is added */\n", - " events.on('output_added.OutputArea', handleAddOutput);\n", - "\n", - " /**\n", - " * Register the mime type and append_mime function with output_area\n", - " */\n", - " OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n", - " /* Is output safe? */\n", - " safe: true,\n", - " /* Index of renderer in `output_area.display_order` */\n", - " index: 0\n", - " });\n", - " }\n", - "\n", - " // register the mime type if in Jupyter Notebook environment and previously unregistered\n", - " if (root.Jupyter !== undefined) {\n", - " var events = require('base/js/events');\n", - " var OutputArea = require('notebook/js/outputarea').OutputArea;\n", - "\n", - " if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n", - " register_renderer(events, OutputArea);\n", - " }\n", - " }\n", - "\n", - " \n", - " if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n", - " root._bokeh_timeout = Date.now() + 5000;\n", - " root._bokeh_failed_load = false;\n", - " }\n", - "\n", - " var NB_LOAD_WARNING = {'data': {'text/html':\n", - " \"
\\n\"+\n", - " \"

\\n\"+\n", - " \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n", - " \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n", - " \"

\\n\"+\n", - " \"
    \\n\"+\n", - " \"
  • re-rerun `output_notebook()` to attempt to load from CDN again, or
  • \\n\"+\n", - " \"
  • use INLINE resources instead, as so:
  • \\n\"+\n", - " \"
\\n\"+\n", - " \"\\n\"+\n", - " \"from bokeh.resources import INLINE\\n\"+\n", - " \"output_notebook(resources=INLINE)\\n\"+\n", - " \"\\n\"+\n", - " \"
\"}};\n", - "\n", - " function display_loaded() {\n", - " var el = document.getElementById(\"2041\");\n", - " if (el != null) {\n", - " el.textContent = \"BokehJS is loading...\";\n", - " }\n", - " if (root.Bokeh !== undefined) {\n", - " if (el != null) {\n", - " el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n", - " }\n", - " } else if (Date.now() < root._bokeh_timeout) {\n", - " setTimeout(display_loaded, 100)\n", - " }\n", - " }\n", - "\n", - "\n", - " function run_callbacks() {\n", - " try {\n", - " root._bokeh_onload_callbacks.forEach(function(callback) { callback() });\n", - " }\n", - " finally {\n", - " delete root._bokeh_onload_callbacks\n", - " }\n", - " console.info(\"Bokeh: all callbacks have finished\");\n", - " }\n", - "\n", - " function load_libs(js_urls, callback) {\n", - " root._bokeh_onload_callbacks.push(callback);\n", - " if (root._bokeh_is_loading > 0) {\n", - " console.log(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n", - " return null;\n", - " }\n", - " if (js_urls == null || js_urls.length === 0) {\n", - " run_callbacks();\n", - " return null;\n", - " }\n", - " console.log(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n", - " root._bokeh_is_loading = js_urls.length;\n", - " for (var i = 0; i < js_urls.length; i++) {\n", - " var url = js_urls[i];\n", - " var s = document.createElement('script');\n", - " s.src = url;\n", - " s.async = false;\n", - " s.onreadystatechange = s.onload = function() {\n", - " root._bokeh_is_loading--;\n", - " if (root._bokeh_is_loading === 0) {\n", - " console.log(\"Bokeh: all BokehJS libraries loaded\");\n", - " run_callbacks()\n", - " }\n", - " };\n", - " s.onerror = function() {\n", - " console.warn(\"failed to load library \" + url);\n", - " };\n", - " console.log(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", - " document.getElementsByTagName(\"head\")[0].appendChild(s);\n", - " }\n", - " };var element = document.getElementById(\"2041\");\n", - " if (element == null) {\n", - " console.log(\"Bokeh: ERROR: autoload.js configured with elementid '2041' but no matching script tag was found. \")\n", - " return false;\n", - " }\n", - "\n", - " var js_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-1.0.4.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.0.4.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.0.4.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-gl-1.0.4.min.js\"];\n", - "\n", - " var inline_js = [\n", - " function(Bokeh) {\n", - " Bokeh.set_log_level(\"info\");\n", - " },\n", - " \n", - " function(Bokeh) {\n", - " \n", - " },\n", - " function(Bokeh) {\n", - " console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/release/bokeh-1.0.4.min.css\");\n", - " Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/release/bokeh-1.0.4.min.css\");\n", - " console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.0.4.min.css\");\n", - " Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.0.4.min.css\");\n", - " console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/release/bokeh-tables-1.0.4.min.css\");\n", - " Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.0.4.min.css\");\n", - " }\n", - " ];\n", - "\n", - " function run_inline_js() {\n", - " \n", - " if ((root.Bokeh !== undefined) || (force === true)) {\n", - " for (var i = 0; i < inline_js.length; i++) {\n", - " inline_js[i].call(root, root.Bokeh);\n", - " }if (force === true) {\n", - " display_loaded();\n", - " }} else if (Date.now() < root._bokeh_timeout) {\n", - " setTimeout(run_inline_js, 100);\n", - " } else if (!root._bokeh_failed_load) {\n", - " console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n", - " root._bokeh_failed_load = true;\n", - " } else if (force !== true) {\n", - " var cell = $(document.getElementById(\"2041\")).parents('.cell').data().cell;\n", - " cell.output_area.append_execute_result(NB_LOAD_WARNING)\n", - " }\n", - "\n", - " }\n", - "\n", - " if (root._bokeh_is_loading === 0) {\n", - " console.log(\"Bokeh: BokehJS loaded, going straight to plotting\");\n", - " run_inline_js();\n", - " } else {\n", - " load_libs(js_urls, function() {\n", - " console.log(\"Bokeh: BokehJS plotting callback run at\", now());\n", - " run_inline_js();\n", - " });\n", - " }\n", - "}(window));" - ], - "application/vnd.bokehjs_load.v0+json": "\n(function(root) {\n function now() {\n return new Date();\n }\n\n var force = true;\n\n if (typeof (root._bokeh_onload_callbacks) === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\n \n\n \n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n var NB_LOAD_WARNING = {'data': {'text/html':\n \"
\\n\"+\n \"

\\n\"+\n \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n \"

\\n\"+\n \"
    \\n\"+\n \"
  • re-rerun `output_notebook()` to attempt to load from CDN again, or
  • \\n\"+\n \"
  • use INLINE resources instead, as so:
  • \\n\"+\n \"
\\n\"+\n \"\\n\"+\n \"from bokeh.resources import INLINE\\n\"+\n \"output_notebook(resources=INLINE)\\n\"+\n \"\\n\"+\n \"
\"}};\n\n function display_loaded() {\n var el = document.getElementById(\"2041\");\n if (el != null) {\n el.textContent = \"BokehJS is loading...\";\n }\n if (root.Bokeh !== undefined) {\n if (el != null) {\n el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n }\n } else if (Date.now() < root._bokeh_timeout) {\n setTimeout(display_loaded, 100)\n }\n }\n\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) { callback() });\n }\n finally {\n delete root._bokeh_onload_callbacks\n }\n console.info(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(js_urls, callback) {\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.log(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls == null || js_urls.length === 0) {\n run_callbacks();\n return null;\n }\n console.log(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n root._bokeh_is_loading = js_urls.length;\n for (var i = 0; i < js_urls.length; i++) {\n var url = js_urls[i];\n var s = document.createElement('script');\n s.src = url;\n s.async = false;\n s.onreadystatechange = s.onload = function() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.log(\"Bokeh: all BokehJS libraries loaded\");\n run_callbacks()\n }\n };\n s.onerror = function() {\n console.warn(\"failed to load library \" + url);\n };\n console.log(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.getElementsByTagName(\"head\")[0].appendChild(s);\n }\n };var element = document.getElementById(\"2041\");\n if (element == null) {\n console.log(\"Bokeh: ERROR: autoload.js configured with elementid '2041' but no matching script tag was found. \")\n return false;\n }\n\n var js_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-1.0.4.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.0.4.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.0.4.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-gl-1.0.4.min.js\"];\n\n var inline_js = [\n function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\n \n function(Bokeh) {\n \n },\n function(Bokeh) {\n console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/release/bokeh-1.0.4.min.css\");\n Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/release/bokeh-1.0.4.min.css\");\n console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.0.4.min.css\");\n Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.0.4.min.css\");\n console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/release/bokeh-tables-1.0.4.min.css\");\n Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.0.4.min.css\");\n }\n ];\n\n function run_inline_js() {\n \n if ((root.Bokeh !== undefined) || (force === true)) {\n for (var i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }if (force === true) {\n display_loaded();\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n } else if (force !== true) {\n var cell = $(document.getElementById(\"2041\")).parents('.cell').data().cell;\n cell.output_area.append_execute_result(NB_LOAD_WARNING)\n }\n\n }\n\n if (root._bokeh_is_loading === 0) {\n console.log(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(js_urls, function() {\n console.log(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));" - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "import bokeh\n", - "import bokeh.plotting as bp\n", - "bp.output_notebook()\n", - "\n", - "import datetime\n", - "import socket\n", - "def get_compact_timestamp():\n", - " now = datetime.datetime.now()\n", - " return now.strftime(\"%Y%m%d.%H%M%S\")\n", - "\n", - "def _save_figure_to_bucket(fig, name, title=None, export_format=\"html\"):\n", - " now = get_compact_timestamp()\n", - " fname = f\"{name}.{now:s}.{export_format}\"\n", - " title = title or name\n", - " if fname.endswith('.png'):\n", - " bokeh.io.export_png(p, os.path.join(\"/tmp\", fname))\n", - " else:\n", - " bp.save(p, os.path.join(\"/tmp\", fname), title=title, \n", - " resources=bokeh.resources.CDN)\n", - " hostname = socket.gethostname()\n", - " GCP_PROJECT=\"edge-probing\"\n", - " !gsutil cp /tmp/$fname gs://$GCP_PROJECT/$hostname/plots/$fname\n", - " !gsutil acl ch -u AllUsers:R gs://$GCP_PROJECT/$hostname/plots/$fname\n", - " url = f\"https://storage.googleapis.com/{GCP_PROJECT}/{hostname}/plots/{fname}\"\n", - " print(f\"Public URL: {url}\")\n", - " return url" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [], - "source": [ - "ID_COLS = ['run', 'task', 'split']\n", - "\n", - "def agg_label_group(df, task_predicate, label_predicate, group_name):\n", - " agg_map = {k:\"sum\" for k in df.columns if k.endswith(\"_count\")}\n", - " mask = df['task'].map(task_predicate) & df['label'].map(label_predicate)\n", - " sdf = df[mask].groupby(by=ID_COLS).agg(agg_map).reset_index()\n", - " sdf['label'] = group_name\n", - " return sdf\n", - "\n", - "def agg_stratifier_group(df, stratifier, key_predicate, group_name):\n", - " agg_map = {k:\"sum\" for k in df.columns if k.endswith(\"_count\")}\n", - " # Use this for short-circuit evaluation, so we don't call key_predicate on invalid keys\n", - " mask = [(s == stratifier and key_predicate(key)) \n", - " for s, key in zip(df['stratifier'], df['stratum_key'])]\n", - " sdf = df[mask].groupby(by=ID_COLS).agg(agg_map).reset_index()\n", - " sdf['label'] = group_name\n", - " return sdf \n", - "\n", - "def load_scores_file(filename, tag=None, seed=None):\n", - " df = pd.read_csv(filename, sep=\"\\t\", header=0)\n", - " df.drop(['Unnamed: 0'], axis='columns', inplace=True)\n", - " # df['task_raw'] = df['task'].copy()\n", - " df['task'] = df['task'].map(analysis.clean_task_name)\n", - " if not \"stratifier\" in df.columns:\n", - " df[\"stratifier\"] = None\n", - " if not \"stratum_key\" in df.columns:\n", - " df[\"stratum_key\"] = 0\n", - " \n", - " ###\n", - " # Add additional custom aggregations\n", - " _eg = []\n", - " # SRL core, non-core, and cleaned micro F1\n", - " _eg.append(agg_label_group(df, analysis.is_srl_task, analysis.is_core_role, \"_core_\"))\n", - " _eg.append(agg_label_group(df, analysis.is_srl_task, analysis.is_non_core_role, \"_non_core_\"))\n", - " _eg.append(agg_label_group(df, analysis.is_srl_task, analysis.is_core_or_noncore, \"_clean_micro_\"))\n", - " # Constituents: split into POS, nonterminals\n", - " _eg.append(agg_stratifier_group(df, 'info.height', lambda x: int(x) == 1, \"_pos_\"))\n", - " _eg.append(agg_stratifier_group(df, 'info.height', lambda x: int(x) > 1, \"_nonterminal_\"))\n", - " # Relations: ignore negative class (no_relation)\n", - " _eg.append(agg_label_group(df, analysis.is_relation_task, analysis.is_positive_relation, \"_clean_micro_\"))\n", - " df = pd.concat([df] + _eg, ignore_index=True, sort=False)\n", - " \n", - " df.insert(0, \"exp_name\", df['run'].map(lambda p: os.path.basename(os.path.dirname(p.strip(\"/\")))))\n", - " df.insert(1, \"exp_type\", df['exp_name'].map(analysis.get_exp_type))\n", - " df.insert(1, \"layer_num\", df['exp_name'].map(analysis.get_layer_num))\n", - " if tag is not None:\n", - " df.insert(0, \"tag\", tag)\n", - " df.insert(1, \"seed\", seed)\n", - " return df" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": { - "scrolled": false - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "['coref-ontonotes-conll' 'dep-labeling-ewt' 'dpr' 'ner-ontonotes'\n", - " 'nonterminal-ontonotes' 'pos-ontonotes' 'rel-semeval' 'rel-tacred' 'spr1'\n", - " 'spr2' 'srl-conll2012']\n", - "['bert-base-uncased-lex' 'bert-base-uncased-mix'\n", - " 'bert-base-uncased-mix-pre' 'bert-large-uncased-lex'\n", - " 'bert-large-uncased-mix' 'bert-large-uncased-mix-pre']\n" - ] - } - ], - "source": [ - "score_files = []\n", - "score_files = [\n", - "# (\"base\", \"/nfs/jsalt/exp/edges-20190211-perlayer/scores.tsv\"),\n", - "# (\"base\", \"/nfs/jsalt/exp/edges-20190213-perlayer-rerun/scores.tsv\"),\n", - " (\"base\", \"/nfs/jsalt/exp/edges-20190217-mix-pre/scores.tsv\"),\n", - " (\"base\", \"/nfs/jsalt/exp/edges-20190218-mix-pre/scores.tsv\"),\n", - " (\"base\", \"/nfs/jsalt/exp/edges-20190219-perlayer/scores.tsv\"),\n", - "]\n", - "dfs = []\n", - "for tag, score_file in score_files:\n", - " df = load_scores_file(score_file, tag=tag)\n", - " dfs.append(df)\n", - "\n", - "df = pd.concat(dfs, ignore_index=True, sort=False)\n", - "def _format_display_col(exp_type, layer_num, tag):\n", - " ret = exp_type\n", - " if layer_num:\n", - " ret += f\"-{layer_num}\"\n", - " if tag:\n", - " ret += f\" ({tag})\"\n", - " return ret\n", - "# df['display_col'] = [\"%s (%s)\" % et for et in zip(df.exp_type, df.tag)]\n", - "df['display_col'] = list(map(_format_display_col, df.exp_type, df.layer_num, df.tag))\n", - "print(df['task'].unique())\n", - "print(df['exp_type'].unique())" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [], - "source": [ - "analysis.score_from_confusion_matrix(df)\n", - "\n", - "##\n", - "# Set 'score' column for task-appropriate metric\n", - "def _get_final_score(row):\n", - " if row['task'] == 'noun-verb':\n", - " return row['accuracy'], row['accuracy_errn95']\n", - " else:\n", - " return row['f1_score'], row['f1_errn95']\n", - "\n", - "df['score'], df['score_errn95'] = zip(*(_get_final_score(row) for i, row in df.iterrows()))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Compute clean metrics for each task\n", - "\n", - "For most tasks this is just the micro or macro average F1, but we need to ignore the 0 label for coref, and drop references and continuations for SRL." - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "418\n" - ] - }, - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
tagseedexp_namelayer_numexp_typelabelnum_epochsnum_stepsruntask...precisionrecallf1_scoreaccuracy_errn95precision_errn95recall_errn95f1_errn95scorescore_errn95display_row
0baseNonebert-base-uncased-mix-00-edges-coref-ontonotes...00bert-base-uncased-mix1NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-ba...coref-ontonotes-conll...0.8443000.7602480.8000730.0033460.0098280.0109820.0103730.8000730.010373coref-ontonotes-conll-1
1baseNonebert-base-uncased-mix-01-edges-coref-ontonotes...01bert-base-uncased-mix1NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-ba...coref-ontonotes-conll...0.8489980.8027900.8252480.0031810.0094710.0102350.0098380.8252480.009838coref-ontonotes-conll-1
2baseNonebert-base-uncased-mix-02-edges-coref-ontonotes...02bert-base-uncased-mix1NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-ba...coref-ontonotes-conll...0.8450750.8408540.8429600.0030630.0093310.0094100.0093700.8429600.009370coref-ontonotes-conll-1
3baseNonebert-base-uncased-mix-03-edges-coref-ontonotes...03bert-base-uncased-mix1NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-ba...coref-ontonotes-conll...0.8602280.8437820.8519260.0029710.0090060.0093390.0091690.8519260.009169coref-ontonotes-conll-1
4baseNonebert-base-uncased-mix-04-edges-coref-ontonotes...04bert-base-uncased-mix1NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-ba...coref-ontonotes-conll...0.8731760.8656560.8694000.0028080.0085970.0087720.0086840.8694000.008684coref-ontonotes-conll-1
5baseNonebert-base-uncased-mix-05-edges-coref-ontonotes...05bert-base-uncased-mix1NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-ba...coref-ontonotes-conll...0.8794720.8722010.8758220.0027430.0084100.0085880.0084980.8758220.008498coref-ontonotes-conll-1
6baseNonebert-base-uncased-mix-06-edges-coref-ontonotes...06bert-base-uncased-mix1NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-ba...coref-ontonotes-conll...0.8878240.8778850.8828270.0026670.0081630.0084220.0082910.8828270.008291coref-ontonotes-conll-1
7baseNonebert-base-uncased-mix-07-edges-coref-ontonotes...07bert-base-uncased-mix1NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-ba...coref-ontonotes-conll...0.8986270.8794350.8889280.0025940.0078480.0083760.0081030.8889280.008103coref-ontonotes-conll-1
8baseNonebert-base-uncased-mix-08-edges-coref-ontonotes...08bert-base-uncased-mix1NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-ba...coref-ontonotes-conll...0.9038330.9016530.9027420.0024460.0075930.0076600.0076260.9027420.007626coref-ontonotes-conll-1
9baseNonebert-base-uncased-mix-09-edges-coref-ontonotes...09bert-base-uncased-mix1NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-ba...coref-ontonotes-conll...0.9054450.9021700.9038050.0024320.0075400.0076420.0075910.9038050.007591coref-ontonotes-conll-1
10baseNonebert-base-uncased-mix-10-edges-coref-ontonotes...10bert-base-uncased-mix1NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-ba...coref-ontonotes-conll...0.9069080.9044090.9056570.0024100.0074840.0075630.0075240.9056570.007524coref-ontonotes-conll-1
11baseNonebert-base-uncased-mix-11-edges-coref-ontonotes...11bert-base-uncased-mix1NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-ba...coref-ontonotes-conll...0.9055620.9001030.9028250.0024430.0075450.0077130.0076280.9028250.007628coref-ontonotes-conll-1
12baseNonebert-base-uncased-mix-12-edges-coref-ontonotes...12bert-base-uncased-mix1NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-ba...coref-ontonotes-conll...0.9081060.8952810.9016480.0024520.0074840.0078760.0076750.9016480.007675coref-ontonotes-conll-1
13baseNonebert-large-uncased-mix-00-edges-coref-ontonote...00bert-large-uncased-mix1NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...coref-ontonotes-conll...0.8348450.7766100.8046760.0033350.0099030.0107140.0102930.8046760.010293coref-ontonotes-conll-1
14baseNonebert-large-uncased-mix-01-edges-coref-ontonote...01bert-large-uncased-mix1NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...coref-ontonotes-conll...0.8305270.8069240.8185550.0032560.0097910.0101530.0099690.8185550.009969coref-ontonotes-conll-1
15baseNonebert-large-uncased-mix-02-edges-coref-ontonote...02bert-large-uncased-mix1NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...coref-ontonotes-conll...0.8460280.8015850.8232070.0031990.0095380.0102580.0098850.8232070.009885coref-ontonotes-conll-1
16baseNonebert-large-uncased-mix-03-edges-coref-ontonote...03bert-large-uncased-mix1NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...coref-ontonotes-conll...0.8411450.8098520.8252020.0031940.0095830.0100940.0098320.8252020.009832coref-ontonotes-conll-1
17baseNonebert-large-uncased-mix-04-edges-coref-ontonote...04bert-large-uncased-mix1NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...coref-ontonotes-conll...0.8492130.8274200.8381750.0030910.0093250.0097200.0095190.8381750.009519coref-ontonotes-conll-1
18baseNonebert-large-uncased-mix-05-edges-coref-ontonote...05bert-large-uncased-mix1NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...coref-ontonotes-conll...0.8515780.8320700.8417110.0030610.0092510.0096150.0094300.8417110.009430coref-ontonotes-conll-1
19baseNonebert-large-uncased-mix-06-edges-coref-ontonote...06bert-large-uncased-mix1NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...coref-ontonotes-conll...0.8551860.8279370.8413410.0030580.0092000.0097090.0094470.8413410.009447coref-ontonotes-conll-1
20baseNonebert-large-uncased-mix-07-edges-coref-ontonote...07bert-large-uncased-mix1NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...coref-ontonotes-conll...0.8551030.8355150.8451960.0030300.0091600.0095360.0093440.8451960.009344coref-ontonotes-conll-1
21baseNonebert-large-uncased-mix-08-edges-coref-ontonote...08bert-large-uncased-mix1NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...coref-ontonotes-conll...0.8553360.8503270.8528240.0029710.0090750.0091770.0091250.8528240.009125coref-ontonotes-conll-1
22baseNonebert-large-uncased-mix-09-edges-coref-ontonote...09bert-large-uncased-mix1NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...coref-ontonotes-conll...0.8626900.8494660.8560270.0029350.0089220.0091980.0090580.8560270.009058coref-ontonotes-conll-1
23baseNonebert-large-uncased-mix-10-edges-coref-ontonote...10bert-large-uncased-mix1NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...coref-ontonotes-conll...0.8642020.8615230.8628600.0028770.0088260.0088850.0088550.8628600.008855coref-ontonotes-conll-1
24baseNonebert-large-uncased-mix-11-edges-coref-ontonote...11bert-large-uncased-mix1NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...coref-ontonotes-conll...0.8706140.8761630.8733800.0027770.0086060.0084730.0085390.8733800.008539coref-ontonotes-conll-1
25baseNonebert-large-uncased-mix-12-edges-coref-ontonote...12bert-large-uncased-mix1NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...coref-ontonotes-conll...0.8765560.8732350.8748920.0027550.0084770.0085580.0085180.8748920.008518coref-ontonotes-conll-1
26baseNonebert-large-uncased-mix-13-edges-coref-ontonote...13bert-large-uncased-mix1NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...coref-ontonotes-conll...0.8815090.8892520.8853640.0026520.0082770.0080720.0081730.8853640.008173coref-ontonotes-conll-1
27baseNonebert-large-uncased-mix-14-edges-coref-ontonote...14bert-large-uncased-mix1NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...coref-ontonotes-conll...0.8909120.8932140.8920620.0025730.0080090.0079440.0079760.8920620.007976coref-ontonotes-conll-1
28baseNonebert-large-uncased-mix-15-edges-coref-ontonote...15bert-large-uncased-mix1NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...coref-ontonotes-conll...0.9023220.9037200.9030200.0024450.0076310.0075880.0076090.9030200.007609coref-ontonotes-conll-1
29baseNonebert-large-uncased-mix-16-edges-coref-ontonote...16bert-large-uncased-mix1NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...coref-ontonotes-conll...0.9072130.9076820.9074470.0023900.0074610.0074460.0074540.9074470.007454coref-ontonotes-conll-1
..................................................................
388baseNonebert-base-uncased-mix-08-edges-srl-conll201208bert-base-uncased-mix_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-ba...srl-conll2012...0.9330000.8881040.9099980.0001000.0017650.0021710.0019470.9099980.001947srl-conll2012-_clean_micro_
389baseNonebert-base-uncased-mix-09-edges-srl-conll201209bert-base-uncased-mix_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-ba...srl-conll2012...0.9311130.8844000.9071550.0001010.0017900.0022020.0019750.9071550.001975srl-conll2012-_clean_micro_
390baseNonebert-base-uncased-mix-10-edges-srl-conll201210bert-base-uncased-mix_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-ba...srl-conll2012...0.9303220.8803740.9046590.0001030.0018030.0022350.0019960.9046590.001996srl-conll2012-_clean_micro_
391baseNonebert-base-uncased-mix-11-edges-srl-conll201211bert-base-uncased-mix_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-ba...srl-conll2012...0.9321930.8857830.9083960.0001010.0017760.0021910.0019620.9083960.001962srl-conll2012-_clean_micro_
392baseNonebert-base-uncased-mix-12-edges-srl-conll201212bert-base-uncased-mix_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-ba...srl-conll2012...0.9328500.8899320.9108860.0000990.0017650.0021560.0019410.9108860.001941srl-conll2012-_clean_micro_
393baseNonebert-large-uncased-mix-00-edges-srl-conll201200bert-large-uncased-mix_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...srl-conll2012...0.8673170.7654160.8131870.0001410.0024870.0029180.0026860.8131870.002686srl-conll2012-_clean_micro_
394baseNonebert-large-uncased-mix-01-edges-srl-conll201201bert-large-uncased-mix_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...srl-conll2012...0.8744270.7680090.8177710.0001390.0024350.0029070.0026500.8177710.002650srl-conll2012-_clean_micro_
395baseNonebert-large-uncased-mix-02-edges-srl-conll201202bert-large-uncased-mix_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...srl-conll2012...0.8964210.8087450.8503290.0001270.0022090.0027090.0024340.8503290.002434srl-conll2012-_clean_micro_
396baseNonebert-large-uncased-mix-03-edges-srl-conll201203bert-large-uncased-mix_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...srl-conll2012...0.8869770.7848150.8327740.0001330.0023180.0028300.0025490.8327740.002549srl-conll2012-_clean_micro_
397baseNonebert-large-uncased-mix-04-edges-srl-conll201204bert-large-uncased-mix_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...srl-conll2012...0.9056210.8215740.8615530.0001220.0021140.0026370.0023470.8615530.002347srl-conll2012-_clean_micro_
398baseNonebert-large-uncased-mix-05-edges-srl-conll201205bert-large-uncased-mix_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...srl-conll2012...0.9052100.8248340.8631550.0001220.0021130.0026180.0023390.8631550.002339srl-conll2012-_clean_micro_
399baseNonebert-large-uncased-mix-06-edges-srl-conll201206bert-large-uncased-mix_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...srl-conll2012...0.9061350.8254640.8639200.0001210.0021040.0026140.0023320.8639200.002332srl-conll2012-_clean_micro_
400baseNonebert-large-uncased-mix-07-edges-srl-conll201207bert-large-uncased-mix_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...srl-conll2012...0.9095690.8378240.8722230.0001180.0020580.0025390.0022730.8722230.002273srl-conll2012-_clean_micro_
401baseNonebert-large-uncased-mix-08-edges-srl-conll201208bert-large-uncased-mix_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...srl-conll2012...0.9161350.8540980.8840290.0001130.0019770.0024310.0021810.8840290.002181srl-conll2012-_clean_micro_
402baseNonebert-large-uncased-mix-09-edges-srl-conll201209bert-large-uncased-mix_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...srl-conll2012...0.9139220.8477020.8795670.0001150.0020060.0024750.0022160.8795670.002216srl-conll2012-_clean_micro_
403baseNonebert-large-uncased-mix-10-edges-srl-conll201210bert-large-uncased-mix_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...srl-conll2012...0.9200670.8578890.8878910.0001110.0019340.0024050.0021440.8878910.002144srl-conll2012-_clean_micro_
404baseNonebert-large-uncased-mix-11-edges-srl-conll201211bert-large-uncased-mix_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...srl-conll2012...0.9253130.8756580.8998010.0001050.0018610.0022730.0020460.8998010.002046srl-conll2012-_clean_micro_
405baseNonebert-large-uncased-mix-12-edges-srl-conll201212bert-large-uncased-mix_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...srl-conll2012...0.9302650.8740030.9012570.0001040.0018100.0022860.0020200.9012570.002020srl-conll2012-_clean_micro_
406baseNonebert-large-uncased-mix-13-edges-srl-conll201213bert-large-uncased-mix_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...srl-conll2012...0.9333390.8863750.9092510.0001000.0017630.0021860.0019520.9092510.001952srl-conll2012-_clean_micro_
407baseNonebert-large-uncased-mix-14-edges-srl-conll201214bert-large-uncased-mix_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...srl-conll2012...0.9349320.8927720.9133650.0000980.0017380.0021310.0019150.9133650.001915srl-conll2012-_clean_micro_
408baseNonebert-large-uncased-mix-15-edges-srl-conll201215bert-large-uncased-mix_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...srl-conll2012...0.9353660.8916850.9130030.0000980.0017340.0021400.0019160.9130030.001916srl-conll2012-_clean_micro_
409baseNonebert-large-uncased-mix-16-edges-srl-conll201216bert-large-uncased-mix_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...srl-conll2012...0.9359670.8970190.9160790.0000970.0017220.0020930.0018900.9160790.001890srl-conll2012-_clean_micro_
410baseNonebert-large-uncased-mix-17-edges-srl-conll201217bert-large-uncased-mix_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...srl-conll2012...0.9348130.8952780.9146180.0000970.0017370.0021090.0019050.9146180.001905srl-conll2012-_clean_micro_
411baseNonebert-large-uncased-mix-18-edges-srl-conll201218bert-large-uncased-mix_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...srl-conll2012...0.9326540.8931420.9124710.0000990.0017640.0021280.0019290.9124710.001929srl-conll2012-_clean_micro_
412baseNonebert-large-uncased-mix-19-edges-srl-conll201219bert-large-uncased-mix_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...srl-conll2012...0.9355020.8944140.9144970.0000970.0017300.0021170.0019040.9144970.001904srl-conll2012-_clean_micro_
413baseNonebert-large-uncased-mix-20-edges-srl-conll201220bert-large-uncased-mix_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...srl-conll2012...0.9373760.8969570.9167210.0000960.0017060.0020940.0018800.9167210.001880srl-conll2012-_clean_micro_
414baseNonebert-large-uncased-mix-21-edges-srl-conll201221bert-large-uncased-mix_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...srl-conll2012...0.9353640.8987970.9167160.0000960.0017280.0020770.0018860.9167160.001886srl-conll2012-_clean_micro_
415baseNonebert-large-uncased-mix-22-edges-srl-conll201222bert-large-uncased-mix_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...srl-conll2012...0.9358440.8942780.9145890.0000970.0017260.0021180.0019020.9145890.001902srl-conll2012-_clean_micro_
416baseNonebert-large-uncased-mix-23-edges-srl-conll201223bert-large-uncased-mix_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...srl-conll2012...0.9351550.8983770.9163970.0000960.0017300.0020810.0018900.9163970.001890srl-conll2012-_clean_micro_
417baseNonebert-large-uncased-mix-24-edges-srl-conll201224bert-large-uncased-mix_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...srl-conll2012...0.9356010.8942660.9144660.0000970.0017290.0021180.0019040.9144660.001904srl-conll2012-_clean_micro_
\n", - "

418 rows × 32 columns

\n", - "
" - ], - "text/plain": [ - " tag seed exp_name layer_num \\\n", - "0 base None bert-base-uncased-mix-00-edges-coref-ontonotes... 00 \n", - "1 base None bert-base-uncased-mix-01-edges-coref-ontonotes... 01 \n", - "2 base None bert-base-uncased-mix-02-edges-coref-ontonotes... 02 \n", - "3 base None bert-base-uncased-mix-03-edges-coref-ontonotes... 03 \n", - "4 base None bert-base-uncased-mix-04-edges-coref-ontonotes... 04 \n", - "5 base None bert-base-uncased-mix-05-edges-coref-ontonotes... 05 \n", - "6 base None bert-base-uncased-mix-06-edges-coref-ontonotes... 06 \n", - "7 base None bert-base-uncased-mix-07-edges-coref-ontonotes... 07 \n", - "8 base None bert-base-uncased-mix-08-edges-coref-ontonotes... 08 \n", - "9 base None bert-base-uncased-mix-09-edges-coref-ontonotes... 09 \n", - "10 base None bert-base-uncased-mix-10-edges-coref-ontonotes... 10 \n", - "11 base None bert-base-uncased-mix-11-edges-coref-ontonotes... 11 \n", - "12 base None bert-base-uncased-mix-12-edges-coref-ontonotes... 12 \n", - "13 base None bert-large-uncased-mix-00-edges-coref-ontonote... 00 \n", - "14 base None bert-large-uncased-mix-01-edges-coref-ontonote... 01 \n", - "15 base None bert-large-uncased-mix-02-edges-coref-ontonote... 02 \n", - "16 base None bert-large-uncased-mix-03-edges-coref-ontonote... 03 \n", - "17 base None bert-large-uncased-mix-04-edges-coref-ontonote... 04 \n", - "18 base None bert-large-uncased-mix-05-edges-coref-ontonote... 05 \n", - "19 base None bert-large-uncased-mix-06-edges-coref-ontonote... 06 \n", - "20 base None bert-large-uncased-mix-07-edges-coref-ontonote... 07 \n", - "21 base None bert-large-uncased-mix-08-edges-coref-ontonote... 08 \n", - "22 base None bert-large-uncased-mix-09-edges-coref-ontonote... 09 \n", - "23 base None bert-large-uncased-mix-10-edges-coref-ontonote... 10 \n", - "24 base None bert-large-uncased-mix-11-edges-coref-ontonote... 11 \n", - "25 base None bert-large-uncased-mix-12-edges-coref-ontonote... 12 \n", - "26 base None bert-large-uncased-mix-13-edges-coref-ontonote... 13 \n", - "27 base None bert-large-uncased-mix-14-edges-coref-ontonote... 14 \n", - "28 base None bert-large-uncased-mix-15-edges-coref-ontonote... 15 \n", - "29 base None bert-large-uncased-mix-16-edges-coref-ontonote... 16 \n", - ".. ... ... ... ... \n", - "388 base None bert-base-uncased-mix-08-edges-srl-conll2012 08 \n", - "389 base None bert-base-uncased-mix-09-edges-srl-conll2012 09 \n", - "390 base None bert-base-uncased-mix-10-edges-srl-conll2012 10 \n", - "391 base None bert-base-uncased-mix-11-edges-srl-conll2012 11 \n", - "392 base None bert-base-uncased-mix-12-edges-srl-conll2012 12 \n", - "393 base None bert-large-uncased-mix-00-edges-srl-conll2012 00 \n", - "394 base None bert-large-uncased-mix-01-edges-srl-conll2012 01 \n", - "395 base None bert-large-uncased-mix-02-edges-srl-conll2012 02 \n", - "396 base None bert-large-uncased-mix-03-edges-srl-conll2012 03 \n", - "397 base None bert-large-uncased-mix-04-edges-srl-conll2012 04 \n", - "398 base None bert-large-uncased-mix-05-edges-srl-conll2012 05 \n", - "399 base None bert-large-uncased-mix-06-edges-srl-conll2012 06 \n", - "400 base None bert-large-uncased-mix-07-edges-srl-conll2012 07 \n", - "401 base None bert-large-uncased-mix-08-edges-srl-conll2012 08 \n", - "402 base None bert-large-uncased-mix-09-edges-srl-conll2012 09 \n", - "403 base None bert-large-uncased-mix-10-edges-srl-conll2012 10 \n", - "404 base None bert-large-uncased-mix-11-edges-srl-conll2012 11 \n", - "405 base None bert-large-uncased-mix-12-edges-srl-conll2012 12 \n", - "406 base None bert-large-uncased-mix-13-edges-srl-conll2012 13 \n", - "407 base None bert-large-uncased-mix-14-edges-srl-conll2012 14 \n", - "408 base None bert-large-uncased-mix-15-edges-srl-conll2012 15 \n", - "409 base None bert-large-uncased-mix-16-edges-srl-conll2012 16 \n", - "410 base None bert-large-uncased-mix-17-edges-srl-conll2012 17 \n", - "411 base None bert-large-uncased-mix-18-edges-srl-conll2012 18 \n", - "412 base None bert-large-uncased-mix-19-edges-srl-conll2012 19 \n", - "413 base None bert-large-uncased-mix-20-edges-srl-conll2012 20 \n", - "414 base None bert-large-uncased-mix-21-edges-srl-conll2012 21 \n", - "415 base None bert-large-uncased-mix-22-edges-srl-conll2012 22 \n", - "416 base None bert-large-uncased-mix-23-edges-srl-conll2012 23 \n", - "417 base None bert-large-uncased-mix-24-edges-srl-conll2012 24 \n", - "\n", - " exp_type label num_epochs num_steps \\\n", - "0 bert-base-uncased-mix 1 NaN NaN \n", - "1 bert-base-uncased-mix 1 NaN NaN \n", - "2 bert-base-uncased-mix 1 NaN NaN \n", - "3 bert-base-uncased-mix 1 NaN NaN \n", - "4 bert-base-uncased-mix 1 NaN NaN \n", - "5 bert-base-uncased-mix 1 NaN NaN \n", - "6 bert-base-uncased-mix 1 NaN NaN \n", - "7 bert-base-uncased-mix 1 NaN NaN \n", - "8 bert-base-uncased-mix 1 NaN NaN \n", - "9 bert-base-uncased-mix 1 NaN NaN \n", - "10 bert-base-uncased-mix 1 NaN NaN \n", - "11 bert-base-uncased-mix 1 NaN NaN \n", - "12 bert-base-uncased-mix 1 NaN NaN \n", - "13 bert-large-uncased-mix 1 NaN NaN \n", - "14 bert-large-uncased-mix 1 NaN NaN \n", - "15 bert-large-uncased-mix 1 NaN NaN \n", - "16 bert-large-uncased-mix 1 NaN NaN \n", - "17 bert-large-uncased-mix 1 NaN NaN \n", - "18 bert-large-uncased-mix 1 NaN NaN \n", - "19 bert-large-uncased-mix 1 NaN NaN \n", - "20 bert-large-uncased-mix 1 NaN NaN \n", - "21 bert-large-uncased-mix 1 NaN NaN \n", - "22 bert-large-uncased-mix 1 NaN NaN \n", - "23 bert-large-uncased-mix 1 NaN NaN \n", - "24 bert-large-uncased-mix 1 NaN NaN \n", - "25 bert-large-uncased-mix 1 NaN NaN \n", - "26 bert-large-uncased-mix 1 NaN NaN \n", - "27 bert-large-uncased-mix 1 NaN NaN \n", - "28 bert-large-uncased-mix 1 NaN NaN \n", - "29 bert-large-uncased-mix 1 NaN NaN \n", - ".. ... ... ... ... \n", - "388 bert-base-uncased-mix _clean_micro_ NaN NaN \n", - "389 bert-base-uncased-mix _clean_micro_ NaN NaN \n", - "390 bert-base-uncased-mix _clean_micro_ NaN NaN \n", - "391 bert-base-uncased-mix _clean_micro_ NaN NaN \n", - "392 bert-base-uncased-mix _clean_micro_ NaN NaN \n", - "393 bert-large-uncased-mix _clean_micro_ NaN NaN \n", - "394 bert-large-uncased-mix _clean_micro_ NaN NaN \n", - "395 bert-large-uncased-mix _clean_micro_ NaN NaN \n", - "396 bert-large-uncased-mix _clean_micro_ NaN NaN \n", - "397 bert-large-uncased-mix _clean_micro_ NaN NaN \n", - "398 bert-large-uncased-mix _clean_micro_ NaN NaN \n", - "399 bert-large-uncased-mix _clean_micro_ NaN NaN \n", - "400 bert-large-uncased-mix _clean_micro_ NaN NaN \n", - "401 bert-large-uncased-mix _clean_micro_ NaN NaN \n", - "402 bert-large-uncased-mix _clean_micro_ NaN NaN \n", - "403 bert-large-uncased-mix _clean_micro_ NaN NaN \n", - "404 bert-large-uncased-mix _clean_micro_ NaN NaN \n", - "405 bert-large-uncased-mix _clean_micro_ NaN NaN \n", - "406 bert-large-uncased-mix _clean_micro_ NaN NaN \n", - "407 bert-large-uncased-mix _clean_micro_ NaN NaN \n", - "408 bert-large-uncased-mix _clean_micro_ NaN NaN \n", - "409 bert-large-uncased-mix _clean_micro_ NaN NaN \n", - "410 bert-large-uncased-mix _clean_micro_ NaN NaN \n", - "411 bert-large-uncased-mix _clean_micro_ NaN NaN \n", - "412 bert-large-uncased-mix _clean_micro_ NaN NaN \n", - "413 bert-large-uncased-mix _clean_micro_ NaN NaN \n", - "414 bert-large-uncased-mix _clean_micro_ NaN NaN \n", - "415 bert-large-uncased-mix _clean_micro_ NaN NaN \n", - "416 bert-large-uncased-mix _clean_micro_ NaN NaN \n", - "417 bert-large-uncased-mix _clean_micro_ NaN NaN \n", - "\n", - " run task \\\n", - "0 /nfs/jsalt/exp/edges-20190219-perlayer/bert-ba... coref-ontonotes-conll \n", - "1 /nfs/jsalt/exp/edges-20190219-perlayer/bert-ba... coref-ontonotes-conll \n", - "2 /nfs/jsalt/exp/edges-20190219-perlayer/bert-ba... coref-ontonotes-conll \n", - "3 /nfs/jsalt/exp/edges-20190219-perlayer/bert-ba... coref-ontonotes-conll \n", - "4 /nfs/jsalt/exp/edges-20190219-perlayer/bert-ba... coref-ontonotes-conll \n", - "5 /nfs/jsalt/exp/edges-20190219-perlayer/bert-ba... coref-ontonotes-conll \n", - "6 /nfs/jsalt/exp/edges-20190219-perlayer/bert-ba... coref-ontonotes-conll \n", - "7 /nfs/jsalt/exp/edges-20190219-perlayer/bert-ba... coref-ontonotes-conll \n", - "8 /nfs/jsalt/exp/edges-20190219-perlayer/bert-ba... coref-ontonotes-conll \n", - "9 /nfs/jsalt/exp/edges-20190219-perlayer/bert-ba... coref-ontonotes-conll \n", - "10 /nfs/jsalt/exp/edges-20190219-perlayer/bert-ba... coref-ontonotes-conll \n", - "11 /nfs/jsalt/exp/edges-20190219-perlayer/bert-ba... coref-ontonotes-conll \n", - "12 /nfs/jsalt/exp/edges-20190219-perlayer/bert-ba... coref-ontonotes-conll \n", - "13 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... coref-ontonotes-conll \n", - "14 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... coref-ontonotes-conll \n", - "15 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... coref-ontonotes-conll \n", - "16 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... coref-ontonotes-conll \n", - "17 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... coref-ontonotes-conll \n", - "18 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... coref-ontonotes-conll \n", - "19 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... coref-ontonotes-conll \n", - "20 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... coref-ontonotes-conll \n", - "21 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... coref-ontonotes-conll \n", - "22 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... coref-ontonotes-conll \n", - "23 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... coref-ontonotes-conll \n", - "24 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... coref-ontonotes-conll \n", - "25 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... coref-ontonotes-conll \n", - "26 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... coref-ontonotes-conll \n", - "27 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... coref-ontonotes-conll \n", - "28 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... coref-ontonotes-conll \n", - "29 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... coref-ontonotes-conll \n", - ".. ... ... \n", - "388 /nfs/jsalt/exp/edges-20190219-perlayer/bert-ba... srl-conll2012 \n", - "389 /nfs/jsalt/exp/edges-20190219-perlayer/bert-ba... srl-conll2012 \n", - "390 /nfs/jsalt/exp/edges-20190219-perlayer/bert-ba... srl-conll2012 \n", - "391 /nfs/jsalt/exp/edges-20190219-perlayer/bert-ba... srl-conll2012 \n", - "392 /nfs/jsalt/exp/edges-20190219-perlayer/bert-ba... srl-conll2012 \n", - "393 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... srl-conll2012 \n", - "394 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... srl-conll2012 \n", - "395 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... srl-conll2012 \n", - "396 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... srl-conll2012 \n", - "397 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... srl-conll2012 \n", - "398 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... srl-conll2012 \n", - "399 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... srl-conll2012 \n", - "400 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... srl-conll2012 \n", - "401 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... srl-conll2012 \n", - "402 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... srl-conll2012 \n", - "403 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... srl-conll2012 \n", - "404 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... srl-conll2012 \n", - "405 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... srl-conll2012 \n", - "406 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... srl-conll2012 \n", - "407 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... srl-conll2012 \n", - "408 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... srl-conll2012 \n", - "409 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... srl-conll2012 \n", - "410 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... srl-conll2012 \n", - "411 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... srl-conll2012 \n", - "412 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... srl-conll2012 \n", - "413 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... srl-conll2012 \n", - "414 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... srl-conll2012 \n", - "415 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... srl-conll2012 \n", - "416 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... srl-conll2012 \n", - "417 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... srl-conll2012 \n", - "\n", - " ... precision recall f1_score \\\n", - "0 ... 0.844300 0.760248 0.800073 \n", - "1 ... 0.848998 0.802790 0.825248 \n", - "2 ... 0.845075 0.840854 0.842960 \n", - "3 ... 0.860228 0.843782 0.851926 \n", - "4 ... 0.873176 0.865656 0.869400 \n", - "5 ... 0.879472 0.872201 0.875822 \n", - "6 ... 0.887824 0.877885 0.882827 \n", - "7 ... 0.898627 0.879435 0.888928 \n", - "8 ... 0.903833 0.901653 0.902742 \n", - "9 ... 0.905445 0.902170 0.903805 \n", - "10 ... 0.906908 0.904409 0.905657 \n", - "11 ... 0.905562 0.900103 0.902825 \n", - "12 ... 0.908106 0.895281 0.901648 \n", - "13 ... 0.834845 0.776610 0.804676 \n", - "14 ... 0.830527 0.806924 0.818555 \n", - "15 ... 0.846028 0.801585 0.823207 \n", - "16 ... 0.841145 0.809852 0.825202 \n", - "17 ... 0.849213 0.827420 0.838175 \n", - "18 ... 0.851578 0.832070 0.841711 \n", - "19 ... 0.855186 0.827937 0.841341 \n", - "20 ... 0.855103 0.835515 0.845196 \n", - "21 ... 0.855336 0.850327 0.852824 \n", - "22 ... 0.862690 0.849466 0.856027 \n", - "23 ... 0.864202 0.861523 0.862860 \n", - "24 ... 0.870614 0.876163 0.873380 \n", - "25 ... 0.876556 0.873235 0.874892 \n", - "26 ... 0.881509 0.889252 0.885364 \n", - "27 ... 0.890912 0.893214 0.892062 \n", - "28 ... 0.902322 0.903720 0.903020 \n", - "29 ... 0.907213 0.907682 0.907447 \n", - ".. ... ... ... ... \n", - "388 ... 0.933000 0.888104 0.909998 \n", - "389 ... 0.931113 0.884400 0.907155 \n", - "390 ... 0.930322 0.880374 0.904659 \n", - "391 ... 0.932193 0.885783 0.908396 \n", - "392 ... 0.932850 0.889932 0.910886 \n", - "393 ... 0.867317 0.765416 0.813187 \n", - "394 ... 0.874427 0.768009 0.817771 \n", - "395 ... 0.896421 0.808745 0.850329 \n", - "396 ... 0.886977 0.784815 0.832774 \n", - "397 ... 0.905621 0.821574 0.861553 \n", - "398 ... 0.905210 0.824834 0.863155 \n", - "399 ... 0.906135 0.825464 0.863920 \n", - "400 ... 0.909569 0.837824 0.872223 \n", - "401 ... 0.916135 0.854098 0.884029 \n", - "402 ... 0.913922 0.847702 0.879567 \n", - "403 ... 0.920067 0.857889 0.887891 \n", - "404 ... 0.925313 0.875658 0.899801 \n", - "405 ... 0.930265 0.874003 0.901257 \n", - "406 ... 0.933339 0.886375 0.909251 \n", - "407 ... 0.934932 0.892772 0.913365 \n", - "408 ... 0.935366 0.891685 0.913003 \n", - "409 ... 0.935967 0.897019 0.916079 \n", - "410 ... 0.934813 0.895278 0.914618 \n", - "411 ... 0.932654 0.893142 0.912471 \n", - "412 ... 0.935502 0.894414 0.914497 \n", - "413 ... 0.937376 0.896957 0.916721 \n", - "414 ... 0.935364 0.898797 0.916716 \n", - "415 ... 0.935844 0.894278 0.914589 \n", - "416 ... 0.935155 0.898377 0.916397 \n", - "417 ... 0.935601 0.894266 0.914466 \n", - "\n", - " accuracy_errn95 precision_errn95 recall_errn95 f1_errn95 score \\\n", - "0 0.003346 0.009828 0.010982 0.010373 0.800073 \n", - "1 0.003181 0.009471 0.010235 0.009838 0.825248 \n", - "2 0.003063 0.009331 0.009410 0.009370 0.842960 \n", - "3 0.002971 0.009006 0.009339 0.009169 0.851926 \n", - "4 0.002808 0.008597 0.008772 0.008684 0.869400 \n", - "5 0.002743 0.008410 0.008588 0.008498 0.875822 \n", - "6 0.002667 0.008163 0.008422 0.008291 0.882827 \n", - "7 0.002594 0.007848 0.008376 0.008103 0.888928 \n", - "8 0.002446 0.007593 0.007660 0.007626 0.902742 \n", - "9 0.002432 0.007540 0.007642 0.007591 0.903805 \n", - "10 0.002410 0.007484 0.007563 0.007524 0.905657 \n", - "11 0.002443 0.007545 0.007713 0.007628 0.902825 \n", - "12 0.002452 0.007484 0.007876 0.007675 0.901648 \n", - "13 0.003335 0.009903 0.010714 0.010293 0.804676 \n", - "14 0.003256 0.009791 0.010153 0.009969 0.818555 \n", - "15 0.003199 0.009538 0.010258 0.009885 0.823207 \n", - "16 0.003194 0.009583 0.010094 0.009832 0.825202 \n", - "17 0.003091 0.009325 0.009720 0.009519 0.838175 \n", - "18 0.003061 0.009251 0.009615 0.009430 0.841711 \n", - "19 0.003058 0.009200 0.009709 0.009447 0.841341 \n", - "20 0.003030 0.009160 0.009536 0.009344 0.845196 \n", - "21 0.002971 0.009075 0.009177 0.009125 0.852824 \n", - "22 0.002935 0.008922 0.009198 0.009058 0.856027 \n", - "23 0.002877 0.008826 0.008885 0.008855 0.862860 \n", - "24 0.002777 0.008606 0.008473 0.008539 0.873380 \n", - "25 0.002755 0.008477 0.008558 0.008518 0.874892 \n", - "26 0.002652 0.008277 0.008072 0.008173 0.885364 \n", - "27 0.002573 0.008009 0.007944 0.007976 0.892062 \n", - "28 0.002445 0.007631 0.007588 0.007609 0.903020 \n", - "29 0.002390 0.007461 0.007446 0.007454 0.907447 \n", - ".. ... ... ... ... ... \n", - "388 0.000100 0.001765 0.002171 0.001947 0.909998 \n", - "389 0.000101 0.001790 0.002202 0.001975 0.907155 \n", - "390 0.000103 0.001803 0.002235 0.001996 0.904659 \n", - "391 0.000101 0.001776 0.002191 0.001962 0.908396 \n", - "392 0.000099 0.001765 0.002156 0.001941 0.910886 \n", - "393 0.000141 0.002487 0.002918 0.002686 0.813187 \n", - "394 0.000139 0.002435 0.002907 0.002650 0.817771 \n", - "395 0.000127 0.002209 0.002709 0.002434 0.850329 \n", - "396 0.000133 0.002318 0.002830 0.002549 0.832774 \n", - "397 0.000122 0.002114 0.002637 0.002347 0.861553 \n", - "398 0.000122 0.002113 0.002618 0.002339 0.863155 \n", - "399 0.000121 0.002104 0.002614 0.002332 0.863920 \n", - "400 0.000118 0.002058 0.002539 0.002273 0.872223 \n", - "401 0.000113 0.001977 0.002431 0.002181 0.884029 \n", - "402 0.000115 0.002006 0.002475 0.002216 0.879567 \n", - "403 0.000111 0.001934 0.002405 0.002144 0.887891 \n", - "404 0.000105 0.001861 0.002273 0.002046 0.899801 \n", - "405 0.000104 0.001810 0.002286 0.002020 0.901257 \n", - "406 0.000100 0.001763 0.002186 0.001952 0.909251 \n", - "407 0.000098 0.001738 0.002131 0.001915 0.913365 \n", - "408 0.000098 0.001734 0.002140 0.001916 0.913003 \n", - "409 0.000097 0.001722 0.002093 0.001890 0.916079 \n", - "410 0.000097 0.001737 0.002109 0.001905 0.914618 \n", - "411 0.000099 0.001764 0.002128 0.001929 0.912471 \n", - "412 0.000097 0.001730 0.002117 0.001904 0.914497 \n", - "413 0.000096 0.001706 0.002094 0.001880 0.916721 \n", - "414 0.000096 0.001728 0.002077 0.001886 0.916716 \n", - "415 0.000097 0.001726 0.002118 0.001902 0.914589 \n", - "416 0.000096 0.001730 0.002081 0.001890 0.916397 \n", - "417 0.000097 0.001729 0.002118 0.001904 0.914466 \n", - "\n", - " score_errn95 display_row \n", - "0 0.010373 coref-ontonotes-conll-1 \n", - "1 0.009838 coref-ontonotes-conll-1 \n", - "2 0.009370 coref-ontonotes-conll-1 \n", - "3 0.009169 coref-ontonotes-conll-1 \n", - "4 0.008684 coref-ontonotes-conll-1 \n", - "5 0.008498 coref-ontonotes-conll-1 \n", - "6 0.008291 coref-ontonotes-conll-1 \n", - "7 0.008103 coref-ontonotes-conll-1 \n", - "8 0.007626 coref-ontonotes-conll-1 \n", - "9 0.007591 coref-ontonotes-conll-1 \n", - "10 0.007524 coref-ontonotes-conll-1 \n", - "11 0.007628 coref-ontonotes-conll-1 \n", - "12 0.007675 coref-ontonotes-conll-1 \n", - "13 0.010293 coref-ontonotes-conll-1 \n", - "14 0.009969 coref-ontonotes-conll-1 \n", - "15 0.009885 coref-ontonotes-conll-1 \n", - "16 0.009832 coref-ontonotes-conll-1 \n", - "17 0.009519 coref-ontonotes-conll-1 \n", - "18 0.009430 coref-ontonotes-conll-1 \n", - "19 0.009447 coref-ontonotes-conll-1 \n", - "20 0.009344 coref-ontonotes-conll-1 \n", - "21 0.009125 coref-ontonotes-conll-1 \n", - "22 0.009058 coref-ontonotes-conll-1 \n", - "23 0.008855 coref-ontonotes-conll-1 \n", - "24 0.008539 coref-ontonotes-conll-1 \n", - "25 0.008518 coref-ontonotes-conll-1 \n", - "26 0.008173 coref-ontonotes-conll-1 \n", - "27 0.007976 coref-ontonotes-conll-1 \n", - "28 0.007609 coref-ontonotes-conll-1 \n", - "29 0.007454 coref-ontonotes-conll-1 \n", - ".. ... ... \n", - "388 0.001947 srl-conll2012-_clean_micro_ \n", - "389 0.001975 srl-conll2012-_clean_micro_ \n", - "390 0.001996 srl-conll2012-_clean_micro_ \n", - "391 0.001962 srl-conll2012-_clean_micro_ \n", - "392 0.001941 srl-conll2012-_clean_micro_ \n", - "393 0.002686 srl-conll2012-_clean_micro_ \n", - "394 0.002650 srl-conll2012-_clean_micro_ \n", - "395 0.002434 srl-conll2012-_clean_micro_ \n", - "396 0.002549 srl-conll2012-_clean_micro_ \n", - "397 0.002347 srl-conll2012-_clean_micro_ \n", - "398 0.002339 srl-conll2012-_clean_micro_ \n", - "399 0.002332 srl-conll2012-_clean_micro_ \n", - "400 0.002273 srl-conll2012-_clean_micro_ \n", - "401 0.002181 srl-conll2012-_clean_micro_ \n", - "402 0.002216 srl-conll2012-_clean_micro_ \n", - "403 0.002144 srl-conll2012-_clean_micro_ \n", - "404 0.002046 srl-conll2012-_clean_micro_ \n", - "405 0.002020 srl-conll2012-_clean_micro_ \n", - "406 0.001952 srl-conll2012-_clean_micro_ \n", - "407 0.001915 srl-conll2012-_clean_micro_ \n", - "408 0.001916 srl-conll2012-_clean_micro_ \n", - "409 0.001890 srl-conll2012-_clean_micro_ \n", - "410 0.001905 srl-conll2012-_clean_micro_ \n", - "411 0.001929 srl-conll2012-_clean_micro_ \n", - "412 0.001904 srl-conll2012-_clean_micro_ \n", - "413 0.001880 srl-conll2012-_clean_micro_ \n", - "414 0.001886 srl-conll2012-_clean_micro_ \n", - "415 0.001902 srl-conll2012-_clean_micro_ \n", - "416 0.001890 srl-conll2012-_clean_micro_ \n", - "417 0.001904 srl-conll2012-_clean_micro_ \n", - "\n", - "[418 rows x 32 columns]" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# SPLIT = \"test\"\n", - "SPLIT = \"val\"\n", - "mask = df['split'] == SPLIT\n", - "mask &= (df['exp_type'] != \"openai\")\n", - "mask &= df['exp_type'].map(lambda s: '-cased-' not in s) # skip cased BERT for now\n", - "# Skip these tasks\n", - "mask &= (df['task'] != \"constituent-ontonotes\")\n", - "mask &= (df['task'] != \"ner-tacred\")\n", - "mask &= (df['task'] != \"coref-gap\")\n", - "mask &= (df['task'] != \"coref-gap-ontonotes\")\n", - "mask &= (df['task'] != \"noun-verb\")\n", - "# mask &= (df['task'] != \"rel-tacred\")\n", - "# mask &= (df['task'] != \"rel-semeval\")\n", - "\n", - "# Only look at perlayer scores\n", - "mask &= df['layer_num'].notnull()\n", - "\n", - "final_scores = []\n", - "for task in df['task'].unique():\n", - " task_scores = df[mask & (df['task'] == task)]\n", - " if analysis.is_coref_task(task):\n", - " final_scores.append(task_scores[task_scores['label'] == \"1\"])\n", - " elif analysis.is_srl_task(task):\n", - "# final_scores.append(task_scores[task_scores['label'] == '_core_'])\n", - "# final_scores.append(task_scores[task_scores['label'] == '_non_core_'])\n", - " # Use clean version, average only over core or noncore roles.\n", - " final_scores.append(task_scores[task_scores['label'] == '_clean_micro_'])\n", - "# elif task == \"nonterminal-ontonotes\":\n", - "# final_scores.append(task_scores[task_scores['label'] == '_micro_avg_'])\n", - "# final_scores.append(task_scores[task_scores['label'] == '_info.height_2_'])\n", - "# final_scores.append(task_scores[task_scores['label'] == '_info.height_3_'])\n", - "# final_scores.append(task_scores[task_scores['label'] == '_info.height_4_'])\n", - "# final_scores.append(task_scores[task_scores['label'] == '_info.height_5_'])\n", - "# final_scores.append(task_scores[task_scores['label'] == '_info.height_6_'])\n", - "# elif task == \"dep-labeling-ewt\":\n", - "# final_scores.append(task_scores[task_scores['label'] == '_micro_avg_'])\n", - "# final_scores.append(task_scores[task_scores['label'] == '_span_distance_0_'])\n", - "# final_scores.append(task_scores[task_scores['label'] == '_span_distance_1_'])\n", - "# final_scores.append(task_scores[task_scores['label'] == '_span_distance_2_'])\n", - "# final_scores.append(task_scores[task_scores['label'] == '_span_distance_3_'])\n", - "# final_scores.append(task_scores[task_scores['label'] == '_span_distance_4_'])\n", - "# final_scores.append(task_scores[task_scores['label'] == '_span_distance_5_'])\n", - "# final_scores.append(task_scores[task_scores['label'] == '_span_distance_6_'])\n", - "# final_scores.append(task_scores[task_scores['label'] == '_span_distance_7_'])\n", - "# final_scores.append(task_scores[task_scores['label'] == '_span_distance_8_'])\n", - "# final_scores.append(task_scores[task_scores['label'] == '_span_distance_9_'])\n", - "# final_scores.append(task_scores[task_scores['label'] == '_span_distance_10_'])\n", - " elif analysis.is_relation_task(task):\n", - " # Relation tasks include specific \"no_relation\" label\n", - " final_scores.append(task_scores[task_scores['label'] == '_clean_micro_'])\n", - " elif task == \"noun-verb\":\n", - " # Noun-verb reports accuracy on VERB class\n", - " final_scores.append(task_scores[task_scores['label'] == 'VERB'])\n", - " else:\n", - " final_scores.append(task_scores[task_scores['label'] == '_micro_avg_'])\n", - " \n", - "fdf = pd.concat(final_scores, axis=0, ignore_index=True, sort=False)\n", - "# fdf['task_and_metric'] = [\"%s-%s\" % tl for tl in zip(fdf.task, fdf.label)]\n", - "def format_display_row(task, label, seed):\n", - " ret = f\"{task}-{label}\"\n", - " if seed:\n", - " ret += f\"-{seed:d}\"\n", - " return ret\n", - "\n", - "fdf['display_row'] = [format_display_row(*args) for args in zip(fdf.task, fdf.label, fdf.seed)]\n", - "print(len(fdf))\n", - "fdf" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Pivot DataFrame to present each task on a row, and each experiment on a column.\n", - "\n", - "This form is suitable to copy-paste into a spreadsheet." - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": { - "scrolled": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "display_row,bert-base-uncased-mix-00 (base),bert-base-uncased-mix-01 (base),bert-base-uncased-mix-02 (base),bert-base-uncased-mix-03 (base),bert-base-uncased-mix-04 (base),bert-base-uncased-mix-05 (base),bert-base-uncased-mix-06 (base),bert-base-uncased-mix-07 (base),bert-base-uncased-mix-08 (base),bert-base-uncased-mix-09 (base),bert-base-uncased-mix-10 (base),bert-base-uncased-mix-11 (base),bert-base-uncased-mix-12 (base),bert-large-uncased-mix-00 (base),bert-large-uncased-mix-01 (base),bert-large-uncased-mix-02 (base),bert-large-uncased-mix-03 (base),bert-large-uncased-mix-04 (base),bert-large-uncased-mix-05 (base),bert-large-uncased-mix-06 (base),bert-large-uncased-mix-07 (base),bert-large-uncased-mix-08 (base),bert-large-uncased-mix-09 (base),bert-large-uncased-mix-10 (base),bert-large-uncased-mix-11 (base),bert-large-uncased-mix-12 (base),bert-large-uncased-mix-13 (base),bert-large-uncased-mix-14 (base),bert-large-uncased-mix-15 (base),bert-large-uncased-mix-16 (base),bert-large-uncased-mix-17 (base),bert-large-uncased-mix-18 (base),bert-large-uncased-mix-19 (base),bert-large-uncased-mix-20 (base),bert-large-uncased-mix-21 (base),bert-large-uncased-mix-22 (base),bert-large-uncased-mix-23 (base),bert-large-uncased-mix-24 (base)\n", - "pos-ontonotes-_micro_avg_,88.3952,93.4826,94.9644,95.4243,95.9719,96.4355,96.3890,96.4161,96.5560,96.4781,96.5859,96.4020,96.4782,88.5125,91.6603,93.1812,93.7355,94.7419,95.1395,95.3522,95.6536,95.8179,95.8860,96.0748,96.3911,96.6274,96.8306,96.8053,96.6902,96.7856,96.6949,96.7164,96.7759,96.7220,96.7209,96.7089,96.7005,96.6928\n", - "nonterminal-ontonotes-_micro_avg_,75.1997,80.5569,83.0987,84.8947,86.0373,86.4235,86.7595,86.7625,87.2055,87.0436,86.9797,87.2785,87.2441,73.5588,79.5000,80.6049,81.0727,83.7707,84.3295,84.3980,84.1754,84.5357,84.9038,85.6799,86.3901,86.9543,86.8418,86.7555,86.8608,87.1781,86.6804,87.2505,87.1349,87.2282,86.8403,86.6614,86.8610,86.9579\n", - "dep-labeling-ewt-_micro_avg_,85.1990,90.2369,91.2977,92.5571,93.6569,94.0952,94.6465,94.8954,95.1667,95.2115,95.0951,95.3245,95.2172,85.6382,88.1905,89.0475,89.7530,91.5321,91.8202,91.7361,92.0803,92.2286,92.4294,93.1269,94.0032,94.6229,94.9609,95.3445,95.2970,95.5448,95.4705,95.4612,95.6357,95.5997,95.6314,95.5466,95.4966,95.5181\n", - "ner-ontonotes-_micro_avg_,89.8686,93.3274,94.2983,94.4166,95.1909,95.4043,95.5909,95.6814,95.8536,95.9136,95.9984,95.9326,96.0298,90.5993,93.3469,93.2902,93.4857,93.9168,94.5017,94.4693,94.6938,94.7908,94.8924,95.0241,95.4655,95.5142,95.7043,95.8289,96.0386,96.2432,96.1739,96.2881,96.3331,96.3062,96.2056,96.3069,96.2913,96.1444\n", - "srl-conll2012-_clean_micro_,79.4559,85.2654,86.5578,87.7683,89.1407,90.3564,90.3386,91.0484,90.9998,90.7155,90.4659,90.8396,91.0886,81.3187,81.7771,85.0329,83.2774,86.1553,86.3155,86.3920,87.2223,88.4029,87.9567,88.7891,89.9801,90.1257,90.9251,91.3365,91.3003,91.6079,91.4618,91.2471,91.4497,91.6721,91.6716,91.4589,91.6397,91.4466\n", - "coref-ontonotes-conll-1,80.0073,82.5248,84.2960,85.1926,86.9400,87.5822,88.2827,88.8928,90.2742,90.3805,90.5657,90.2825,90.1648,80.4676,81.8555,82.3207,82.5202,83.8175,84.1711,84.1341,84.5196,85.2824,85.6027,86.2860,87.3380,87.4892,88.5364,89.2062,90.3020,90.7447,91.3851,91.9886,91.9993,91.7607,91.9689,92.1066,92.0903,91.9394\n", - "spr1-_micro_avg_,77.8073,78.7641,79.6591,80.3152,80.9008,81.7424,82.0834,82.8600,83.0438,83.5019,83.4576,83.6118,83.5242,77.6625,78.1162,78.4673,78.7330,79.3514,79.5378,79.8145,80.0137,80.2963,80.6650,81.0081,81.1382,81.6835,81.6551,81.9255,82.1486,82.7199,82.9169,83.1592,83.2402,83.4339,83.7572,83.7758,83.9228,83.7205\n", - "spr2-_micro_avg_,80.9978,81.6865,81.7639,82.0067,82.1615,82.2847,82.3746,82.8032,82.6658,82.7218,83.1441,83.0270,83.0014,80.8566,81.0160,80.9607,81.2343,81.2100,81.2858,81.1969,81.2879,81.7174,81.5677,81.9322,81.8894,82.1709,82.3145,81.9463,82.3799,82.3607,82.6493,82.8086,82.7144,82.9268,82.9507,82.7992,82.7872,83.0234\n", - "dpr-_micro_avg_,56.1118,59.2018,56.6392,57.2738,54.5226,54.7192,56.9444,55.7178,58.5143,57.7197,57.4822,59.1484,55.2180,58.0427,61.9289,56.3084,57.7367,60.2128,58.3333,57.6880,56.7059,58.4718,58.9266,58.1622,55.1640,54.5455,55.3086,63.7363,54.2153,58.5928,61.1940,55.5825,67.5462,58.9777,69.0382,69.1293,68.1579,68.9474\n", - "rel-tacred-_clean_micro_,25.2350,32.6096,33.9462,36.8098,41.1104,43.5123,42.9342,47.9556,48.4468,50.3002,50.9781,49.4714,50.8229,27.6130,32.3145,33.2734,34.8592,34.1363,38.5649,38.9005,42.1859,38.8221,43.6824,45.1393,44.1104,44.5568,46.6966,47.5809,48.9427,49.2837,49.2851,51.1853,50.5851,51.1217,52.0103,51.1589,54.7844,54.0361\n", - "rel-semeval-_clean_micro_,58.9330,66.0471,68.6298,70.8558,73.9742,74.6635,77.2542,78.2458,80.2260,81.1677,81.6441,83.2685,82.8699,60.7297,64.5320,65.4454,65.2985,68.1107,68.9065,70.8283,72.1992,72.9841,73.8676,74.2857,75.1748,76.5489,76.6082,77.1363,78.3362,79.9314,81.1825,81.4019,82.2346,83.0461,83.2044,84.1173,83.6120,84.1695\n", - "\n" - ] - } - ], - "source": [ - "# Pivot to wide-form for spreadsheet, and sort in (mostly) stable order.\n", - "sheet_df = fdf.pivot(index=\"display_row\", columns=\"display_col\", values=\"score\")\n", - "sheet_df = sheet_df.reindex(sorted(sheet_df.columns, \n", - " key=exp_type_sort_key), axis=1)\n", - "sheet_df = sheet_df.reindex(sorted(sheet_df.index,\n", - " key=task_sort_key), axis=0)\n", - "\n", - "csv_args = dict(float_format=\"%.4f\")\n", - "print((100*sheet_df).to_csv(**csv_args))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Plot F1 by layer as a bar plot" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
tagseedexp_namelayer_numexp_typelabelnum_epochsnum_stepsruntask...lex_scoreprev_layer_scoredelta_scoreexp_layerprev_score_maxreal_delta_scorekl_unifcontextual_headroomheadroom_fracreal_headroom_frac
0baseNonebert-base-uncased-mix-00-edges-coref-ontonotes...00bert-base-uncased-mix1NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-ba...coref-ontonotes-conll...0.80007300.8000733.618640.0000000.8000730.6321030.1055857.577557.57755
1baseNonebert-base-uncased-mix-01-edges-coref-ontonotes...01bert-base-uncased-mix1NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-ba...coref-ontonotes-conll...0.8000730.8000720.02517543.618640.8000720.02517540.6321030.1055850.2384380.238438
2baseNonebert-base-uncased-mix-02-edges-coref-ontonotes...02bert-base-uncased-mix1NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-ba...coref-ontonotes-conll...0.8000730.8252480.01771163.618640.8252480.01771160.6321030.1055850.1677480.167748
3baseNonebert-base-uncased-mix-03-edges-coref-ontonotes...03bert-base-uncased-mix1NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-ba...coref-ontonotes-conll...0.8000730.842960.00896643.618640.8429600.00896640.6321030.1055850.08492140.0849214
4baseNonebert-base-uncased-mix-04-edges-coref-ontonotes...04bert-base-uncased-mix1NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-ba...coref-ontonotes-conll...0.8000730.8519260.01747383.618640.8519260.01747380.6321030.1055850.1654960.165496
5baseNonebert-base-uncased-mix-05-edges-coref-ontonotes...05bert-base-uncased-mix1NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-ba...coref-ontonotes-conll...0.8000730.86940.006421733.618640.8694000.006421730.6321030.1055850.06082070.0608207
6baseNonebert-base-uncased-mix-06-edges-coref-ontonotes...06bert-base-uncased-mix1NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-ba...coref-ontonotes-conll...0.8000730.8758220.007005183.618640.8758220.007005180.6321030.1055850.06634660.0663466
7baseNonebert-base-uncased-mix-07-edges-coref-ontonotes...07bert-base-uncased-mix1NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-ba...coref-ontonotes-conll...0.8000730.8828270.006100893.618640.8828270.006100890.6321030.1055850.0577820.057782
8baseNonebert-base-uncased-mix-08-edges-coref-ontonotes...08bert-base-uncased-mix1NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-ba...coref-ontonotes-conll...0.8000730.8889280.01381433.618640.8889280.01381430.6321030.1055850.1308360.130836
9baseNonebert-base-uncased-mix-09-edges-coref-ontonotes...09bert-base-uncased-mix1NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-ba...coref-ontonotes-conll...0.8000730.9027420.001062833.618640.9027420.001062830.6321030.1055850.01006610.0100661
10baseNonebert-base-uncased-mix-10-edges-coref-ontonotes...10bert-base-uncased-mix1NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-ba...coref-ontonotes-conll...0.8000730.9038050.001852463.618640.9038050.001852460.6321030.1055850.01754480.0175448
11baseNonebert-base-uncased-mix-11-edges-coref-ontonotes...11bert-base-uncased-mix1NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-ba...coref-ontonotes-conll...0.8000730.905657-0.002832553.618640.905657-0.002832550.6321030.105585-0.0268273-0.0268273
12baseNonebert-base-uncased-mix-12-edges-coref-ontonotes...12bert-base-uncased-mix1NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-ba...coref-ontonotes-conll...0.8000730.902825-0.001176713.618640.905657-0.001176710.6321030.105585-0.0111447-0.0111447
13baseNonebert-large-uncased-mix-00-edges-coref-ontonote...00bert-large-uncased-mix1NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...coref-ontonotes-conll...0.80467600.8046769.471180.0000000.8046760.5982480.1163916.913586.91358
14baseNonebert-large-uncased-mix-01-edges-coref-ontonote...01bert-large-uncased-mix1NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...coref-ontonotes-conll...0.8046760.8046760.01387949.471180.8046760.01387940.5982480.1163910.1192490.119249
15baseNonebert-large-uncased-mix-02-edges-coref-ontonote...02bert-large-uncased-mix1NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...coref-ontonotes-conll...0.8046760.8185550.004651819.471180.8185550.004651810.5982480.1163910.03996720.0399672
16baseNonebert-large-uncased-mix-03-edges-coref-ontonote...03bert-large-uncased-mix1NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...coref-ontonotes-conll...0.8046760.8232070.001994989.471180.8232070.001994980.5982480.1163910.01714040.0171404
17baseNonebert-large-uncased-mix-04-edges-coref-ontonote...04bert-large-uncased-mix1NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...coref-ontonotes-conll...0.8046760.8252020.01297329.471180.8252020.01297320.5982480.1163910.1114630.111463
18baseNonebert-large-uncased-mix-05-edges-coref-ontonote...05bert-large-uncased-mix1NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...coref-ontonotes-conll...0.8046760.8381750.003535959.471180.8381750.003535950.5982480.1163910.03038010.0303801
19baseNonebert-large-uncased-mix-06-edges-coref-ontonote...06bert-large-uncased-mix1NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...coref-ontonotes-conll...0.8046760.841711-0.0003702419.471180.841711-0.0003702410.5982480.116391-0.00318102-0.00318102
20baseNonebert-large-uncased-mix-07-edges-coref-ontonote...07bert-large-uncased-mix1NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...coref-ontonotes-conll...0.8046760.8413410.003854919.471180.8417110.003854910.5982480.1163910.03312050.0331205
21baseNonebert-large-uncased-mix-08-edges-coref-ontonote...08bert-large-uncased-mix1NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...coref-ontonotes-conll...0.8046760.8451960.007628739.471180.8451960.007628730.5982480.1163910.06554420.0655442
22baseNonebert-large-uncased-mix-09-edges-coref-ontonote...09bert-large-uncased-mix1NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...coref-ontonotes-conll...0.8046760.8528240.003202759.471180.8528240.003202750.5982480.1163910.02751720.0275172
23baseNonebert-large-uncased-mix-10-edges-coref-ontonote...10bert-large-uncased-mix1NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...coref-ontonotes-conll...0.8046760.8560270.006833039.471180.8560270.006833030.5982480.1163910.05870780.0587078
24baseNonebert-large-uncased-mix-11-edges-coref-ontonote...11bert-large-uncased-mix1NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...coref-ontonotes-conll...0.8046760.862860.01051969.471180.8628600.01051960.5982480.1163910.09038190.0903819
25baseNonebert-large-uncased-mix-12-edges-coref-ontonote...12bert-large-uncased-mix1NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...coref-ontonotes-conll...0.8046760.873380.001512449.471180.8733800.001512440.5982480.1163910.01299450.0129945
26baseNonebert-large-uncased-mix-13-edges-coref-ontonote...13bert-large-uncased-mix1NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...coref-ontonotes-conll...0.8046760.8748920.01047189.471180.8748920.01047180.5982480.1163910.08997120.0899712
27baseNonebert-large-uncased-mix-14-edges-coref-ontonote...14bert-large-uncased-mix1NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...coref-ontonotes-conll...0.8046760.8853640.006697589.471180.8853640.006697580.5982480.1163910.05754410.0575441
28baseNonebert-large-uncased-mix-15-edges-coref-ontonote...15bert-large-uncased-mix1NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...coref-ontonotes-conll...0.8046760.8920620.01095889.471180.8920620.01095880.5982480.1163910.09415540.0941554
29baseNonebert-large-uncased-mix-16-edges-coref-ontonote...16bert-large-uncased-mix1NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...coref-ontonotes-conll...0.8046760.903020.004426889.471180.9030200.004426880.5982480.1163910.03803470.0380347
..................................................................
388baseNonebert-base-uncased-mix-08-edges-srl-conll201208bert-base-uncased-mix_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-ba...srl-conll2012...0.7945590.910484-0.0004858952.588440.910484-0.0004858951.2104600.116326-0.00417701-0.00417701
389baseNonebert-base-uncased-mix-09-edges-srl-conll201209bert-base-uncased-mix_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-ba...srl-conll2012...0.7945590.909998-0.002843032.588440.910484-0.002843031.2104600.116326-0.0244402-0.0244402
390baseNonebert-base-uncased-mix-10-edges-srl-conll201210bert-base-uncased-mix_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-ba...srl-conll2012...0.7945590.907155-0.002496212.588440.910484-0.002496211.2104600.116326-0.0214587-0.0214587
391baseNonebert-base-uncased-mix-11-edges-srl-conll201211bert-base-uncased-mix_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-ba...srl-conll2012...0.7945590.9046590.003736382.588440.9104840.003736381.2104600.1163260.03211990.0321199
392baseNonebert-base-uncased-mix-12-edges-srl-conll201212bert-base-uncased-mix_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-ba...srl-conll2012...0.7945590.9083960.002489992.588440.9104840.002489991.2104600.1163260.02140530.0214053
393baseNonebert-large-uncased-mix-00-edges-srl-conll201200bert-large-uncased-mix_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...srl-conll2012...0.81318700.8131876.536650.0000000.8131871.3070570.1035357.854247.85424
394baseNonebert-large-uncased-mix-01-edges-srl-conll201201bert-large-uncased-mix_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...srl-conll2012...0.8131870.8131870.0045846.536650.8131870.0045841.3070570.1035350.0442750.044275
395baseNonebert-large-uncased-mix-02-edges-srl-conll201202bert-large-uncased-mix_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...srl-conll2012...0.8131870.8177710.03255816.536650.8177710.03255811.3070570.1035350.3144660.314466
396baseNonebert-large-uncased-mix-03-edges-srl-conll201203bert-large-uncased-mix_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...srl-conll2012...0.8131870.850329-0.01755456.536650.850329-0.01755451.3070570.103535-0.169552-0.169552
397baseNonebert-large-uncased-mix-04-edges-srl-conll201204bert-large-uncased-mix_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...srl-conll2012...0.8131870.8327740.02877856.536650.8503290.02877851.3070570.1035350.277960.27796
398baseNonebert-large-uncased-mix-05-edges-srl-conll201205bert-large-uncased-mix_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...srl-conll2012...0.8131870.8615530.001602266.536650.8615530.001602261.3070570.1035350.01547560.0154756
399baseNonebert-large-uncased-mix-06-edges-srl-conll201206bert-large-uncased-mix_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...srl-conll2012...0.8131870.8631550.0007650176.536650.8631550.0007650171.3070570.1035350.007388990.00738899
400baseNonebert-large-uncased-mix-07-edges-srl-conll201207bert-large-uncased-mix_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...srl-conll2012...0.8131870.863920.008303276.536650.8639200.008303271.3070570.1035350.0801980.080198
401baseNonebert-large-uncased-mix-08-edges-srl-conll201208bert-large-uncased-mix_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...srl-conll2012...0.8131870.8722230.01180616.536650.8722230.01180611.3070570.1035350.114030.11403
402baseNonebert-large-uncased-mix-09-edges-srl-conll201209bert-large-uncased-mix_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...srl-conll2012...0.8131870.884029-0.004461986.536650.884029-0.004461981.3070570.103535-0.0430965-0.0430965
403baseNonebert-large-uncased-mix-10-edges-srl-conll201210bert-large-uncased-mix_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...srl-conll2012...0.8131870.8795670.008323216.536650.8840290.008323211.3070570.1035350.08039060.0803906
404baseNonebert-large-uncased-mix-11-edges-srl-conll201211bert-large-uncased-mix_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...srl-conll2012...0.8131870.8878910.01191026.536650.8878910.01191021.3070570.1035350.1150350.115035
405baseNonebert-large-uncased-mix-12-edges-srl-conll201212bert-large-uncased-mix_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...srl-conll2012...0.8131870.8998010.001455966.536650.8998010.001455961.3070570.1035350.01406250.0140625
406baseNonebert-large-uncased-mix-13-edges-srl-conll201213bert-large-uncased-mix_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...srl-conll2012...0.8131870.9012570.007994236.536650.9012570.007994231.3070570.1035350.0772130.077213
407baseNonebert-large-uncased-mix-14-edges-srl-conll201214bert-large-uncased-mix_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...srl-conll2012...0.8131870.9092510.004114366.536650.9092510.004114361.3070570.1035350.0397390.039739
408baseNonebert-large-uncased-mix-15-edges-srl-conll201215bert-large-uncased-mix_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...srl-conll2012...0.8131870.913365-0.0003620146.536650.913365-0.0003620141.3070570.103535-0.00349654-0.00349654
409baseNonebert-large-uncased-mix-16-edges-srl-conll201216bert-large-uncased-mix_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...srl-conll2012...0.8131870.9130030.003075926.536650.9133650.003075921.3070570.1035350.0297090.029709
410baseNonebert-large-uncased-mix-17-edges-srl-conll201217bert-large-uncased-mix_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...srl-conll2012...0.8131870.916079-0.001460856.536650.916079-0.001460851.3070570.103535-0.0141097-0.0141097
411baseNonebert-large-uncased-mix-18-edges-srl-conll201218bert-large-uncased-mix_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...srl-conll2012...0.8131870.914618-0.002147786.536650.916079-0.002147781.3070570.103535-0.0207446-0.0207446
412baseNonebert-large-uncased-mix-19-edges-srl-conll201219bert-large-uncased-mix_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...srl-conll2012...0.8131870.9124710.002026156.536650.9160790.002026151.3070570.1035350.01956980.0195698
413baseNonebert-large-uncased-mix-20-edges-srl-conll201220bert-large-uncased-mix_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...srl-conll2012...0.8131870.9144970.002224636.536650.9160790.002224631.3070570.1035350.02148680.0214868
414baseNonebert-large-uncased-mix-21-edges-srl-conll201221bert-large-uncased-mix_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...srl-conll2012...0.8131870.916721-5.3509e-066.536650.916721-5.3509e-061.3070570.103535-5.16822e-05-5.16822e-05
415baseNonebert-large-uncased-mix-22-edges-srl-conll201222bert-large-uncased-mix_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...srl-conll2012...0.8131870.916716-0.002127196.536650.916721-0.002127191.3070570.103535-0.0205456-0.0205456
416baseNonebert-large-uncased-mix-23-edges-srl-conll201223bert-large-uncased-mix_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...srl-conll2012...0.8131870.9145890.001808636.536650.9167210.001808631.3070570.1035350.01746880.0174688
417baseNonebert-large-uncased-mix-24-edges-srl-conll201224bert-large-uncased-mix_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190219-perlayer/bert-la...srl-conll2012...0.8131870.916397-0.0019316.536650.916721-0.0019311.3070570.103535-0.0186507-0.0186507
\n", - "

418 rows × 43 columns

\n", - "
" - ], - "text/plain": [ - " tag seed exp_name layer_num \\\n", - "0 base None bert-base-uncased-mix-00-edges-coref-ontonotes... 00 \n", - "1 base None bert-base-uncased-mix-01-edges-coref-ontonotes... 01 \n", - "2 base None bert-base-uncased-mix-02-edges-coref-ontonotes... 02 \n", - "3 base None bert-base-uncased-mix-03-edges-coref-ontonotes... 03 \n", - "4 base None bert-base-uncased-mix-04-edges-coref-ontonotes... 04 \n", - "5 base None bert-base-uncased-mix-05-edges-coref-ontonotes... 05 \n", - "6 base None bert-base-uncased-mix-06-edges-coref-ontonotes... 06 \n", - "7 base None bert-base-uncased-mix-07-edges-coref-ontonotes... 07 \n", - "8 base None bert-base-uncased-mix-08-edges-coref-ontonotes... 08 \n", - "9 base None bert-base-uncased-mix-09-edges-coref-ontonotes... 09 \n", - "10 base None bert-base-uncased-mix-10-edges-coref-ontonotes... 10 \n", - "11 base None bert-base-uncased-mix-11-edges-coref-ontonotes... 11 \n", - "12 base None bert-base-uncased-mix-12-edges-coref-ontonotes... 12 \n", - "13 base None bert-large-uncased-mix-00-edges-coref-ontonote... 00 \n", - "14 base None bert-large-uncased-mix-01-edges-coref-ontonote... 01 \n", - "15 base None bert-large-uncased-mix-02-edges-coref-ontonote... 02 \n", - "16 base None bert-large-uncased-mix-03-edges-coref-ontonote... 03 \n", - "17 base None bert-large-uncased-mix-04-edges-coref-ontonote... 04 \n", - "18 base None bert-large-uncased-mix-05-edges-coref-ontonote... 05 \n", - "19 base None bert-large-uncased-mix-06-edges-coref-ontonote... 06 \n", - "20 base None bert-large-uncased-mix-07-edges-coref-ontonote... 07 \n", - "21 base None bert-large-uncased-mix-08-edges-coref-ontonote... 08 \n", - "22 base None bert-large-uncased-mix-09-edges-coref-ontonote... 09 \n", - "23 base None bert-large-uncased-mix-10-edges-coref-ontonote... 10 \n", - "24 base None bert-large-uncased-mix-11-edges-coref-ontonote... 11 \n", - "25 base None bert-large-uncased-mix-12-edges-coref-ontonote... 12 \n", - "26 base None bert-large-uncased-mix-13-edges-coref-ontonote... 13 \n", - "27 base None bert-large-uncased-mix-14-edges-coref-ontonote... 14 \n", - "28 base None bert-large-uncased-mix-15-edges-coref-ontonote... 15 \n", - "29 base None bert-large-uncased-mix-16-edges-coref-ontonote... 16 \n", - ".. ... ... ... ... \n", - "388 base None bert-base-uncased-mix-08-edges-srl-conll2012 08 \n", - "389 base None bert-base-uncased-mix-09-edges-srl-conll2012 09 \n", - "390 base None bert-base-uncased-mix-10-edges-srl-conll2012 10 \n", - "391 base None bert-base-uncased-mix-11-edges-srl-conll2012 11 \n", - "392 base None bert-base-uncased-mix-12-edges-srl-conll2012 12 \n", - "393 base None bert-large-uncased-mix-00-edges-srl-conll2012 00 \n", - "394 base None bert-large-uncased-mix-01-edges-srl-conll2012 01 \n", - "395 base None bert-large-uncased-mix-02-edges-srl-conll2012 02 \n", - "396 base None bert-large-uncased-mix-03-edges-srl-conll2012 03 \n", - "397 base None bert-large-uncased-mix-04-edges-srl-conll2012 04 \n", - "398 base None bert-large-uncased-mix-05-edges-srl-conll2012 05 \n", - "399 base None bert-large-uncased-mix-06-edges-srl-conll2012 06 \n", - "400 base None bert-large-uncased-mix-07-edges-srl-conll2012 07 \n", - "401 base None bert-large-uncased-mix-08-edges-srl-conll2012 08 \n", - "402 base None bert-large-uncased-mix-09-edges-srl-conll2012 09 \n", - "403 base None bert-large-uncased-mix-10-edges-srl-conll2012 10 \n", - "404 base None bert-large-uncased-mix-11-edges-srl-conll2012 11 \n", - "405 base None bert-large-uncased-mix-12-edges-srl-conll2012 12 \n", - "406 base None bert-large-uncased-mix-13-edges-srl-conll2012 13 \n", - "407 base None bert-large-uncased-mix-14-edges-srl-conll2012 14 \n", - "408 base None bert-large-uncased-mix-15-edges-srl-conll2012 15 \n", - "409 base None bert-large-uncased-mix-16-edges-srl-conll2012 16 \n", - "410 base None bert-large-uncased-mix-17-edges-srl-conll2012 17 \n", - "411 base None bert-large-uncased-mix-18-edges-srl-conll2012 18 \n", - "412 base None bert-large-uncased-mix-19-edges-srl-conll2012 19 \n", - "413 base None bert-large-uncased-mix-20-edges-srl-conll2012 20 \n", - "414 base None bert-large-uncased-mix-21-edges-srl-conll2012 21 \n", - "415 base None bert-large-uncased-mix-22-edges-srl-conll2012 22 \n", - "416 base None bert-large-uncased-mix-23-edges-srl-conll2012 23 \n", - "417 base None bert-large-uncased-mix-24-edges-srl-conll2012 24 \n", - "\n", - " exp_type label num_epochs num_steps \\\n", - "0 bert-base-uncased-mix 1 NaN NaN \n", - "1 bert-base-uncased-mix 1 NaN NaN \n", - "2 bert-base-uncased-mix 1 NaN NaN \n", - "3 bert-base-uncased-mix 1 NaN NaN \n", - "4 bert-base-uncased-mix 1 NaN NaN \n", - "5 bert-base-uncased-mix 1 NaN NaN \n", - "6 bert-base-uncased-mix 1 NaN NaN \n", - "7 bert-base-uncased-mix 1 NaN NaN \n", - "8 bert-base-uncased-mix 1 NaN NaN \n", - "9 bert-base-uncased-mix 1 NaN NaN \n", - "10 bert-base-uncased-mix 1 NaN NaN \n", - "11 bert-base-uncased-mix 1 NaN NaN \n", - "12 bert-base-uncased-mix 1 NaN NaN \n", - "13 bert-large-uncased-mix 1 NaN NaN \n", - "14 bert-large-uncased-mix 1 NaN NaN \n", - "15 bert-large-uncased-mix 1 NaN NaN \n", - "16 bert-large-uncased-mix 1 NaN NaN \n", - "17 bert-large-uncased-mix 1 NaN NaN \n", - "18 bert-large-uncased-mix 1 NaN NaN \n", - "19 bert-large-uncased-mix 1 NaN NaN \n", - "20 bert-large-uncased-mix 1 NaN NaN \n", - "21 bert-large-uncased-mix 1 NaN NaN \n", - "22 bert-large-uncased-mix 1 NaN NaN \n", - "23 bert-large-uncased-mix 1 NaN NaN \n", - "24 bert-large-uncased-mix 1 NaN NaN \n", - "25 bert-large-uncased-mix 1 NaN NaN \n", - "26 bert-large-uncased-mix 1 NaN NaN \n", - "27 bert-large-uncased-mix 1 NaN NaN \n", - "28 bert-large-uncased-mix 1 NaN NaN \n", - "29 bert-large-uncased-mix 1 NaN NaN \n", - ".. ... ... ... ... \n", - "388 bert-base-uncased-mix _clean_micro_ NaN NaN \n", - "389 bert-base-uncased-mix _clean_micro_ NaN NaN \n", - "390 bert-base-uncased-mix _clean_micro_ NaN NaN \n", - "391 bert-base-uncased-mix _clean_micro_ NaN NaN \n", - "392 bert-base-uncased-mix _clean_micro_ NaN NaN \n", - "393 bert-large-uncased-mix _clean_micro_ NaN NaN \n", - "394 bert-large-uncased-mix _clean_micro_ NaN NaN \n", - "395 bert-large-uncased-mix _clean_micro_ NaN NaN \n", - "396 bert-large-uncased-mix _clean_micro_ NaN NaN \n", - "397 bert-large-uncased-mix _clean_micro_ NaN NaN \n", - "398 bert-large-uncased-mix _clean_micro_ NaN NaN \n", - "399 bert-large-uncased-mix _clean_micro_ NaN NaN \n", - "400 bert-large-uncased-mix _clean_micro_ NaN NaN \n", - "401 bert-large-uncased-mix _clean_micro_ NaN NaN \n", - "402 bert-large-uncased-mix _clean_micro_ NaN NaN \n", - "403 bert-large-uncased-mix _clean_micro_ NaN NaN \n", - "404 bert-large-uncased-mix _clean_micro_ NaN NaN \n", - "405 bert-large-uncased-mix _clean_micro_ NaN NaN \n", - "406 bert-large-uncased-mix _clean_micro_ NaN NaN \n", - "407 bert-large-uncased-mix _clean_micro_ NaN NaN \n", - "408 bert-large-uncased-mix _clean_micro_ NaN NaN \n", - "409 bert-large-uncased-mix _clean_micro_ NaN NaN \n", - "410 bert-large-uncased-mix _clean_micro_ NaN NaN \n", - "411 bert-large-uncased-mix _clean_micro_ NaN NaN \n", - "412 bert-large-uncased-mix _clean_micro_ NaN NaN \n", - "413 bert-large-uncased-mix _clean_micro_ NaN NaN \n", - "414 bert-large-uncased-mix _clean_micro_ NaN NaN \n", - "415 bert-large-uncased-mix _clean_micro_ NaN NaN \n", - "416 bert-large-uncased-mix _clean_micro_ NaN NaN \n", - "417 bert-large-uncased-mix _clean_micro_ NaN NaN \n", - "\n", - " run task \\\n", - "0 /nfs/jsalt/exp/edges-20190219-perlayer/bert-ba... coref-ontonotes-conll \n", - "1 /nfs/jsalt/exp/edges-20190219-perlayer/bert-ba... coref-ontonotes-conll \n", - "2 /nfs/jsalt/exp/edges-20190219-perlayer/bert-ba... coref-ontonotes-conll \n", - "3 /nfs/jsalt/exp/edges-20190219-perlayer/bert-ba... coref-ontonotes-conll \n", - "4 /nfs/jsalt/exp/edges-20190219-perlayer/bert-ba... coref-ontonotes-conll \n", - "5 /nfs/jsalt/exp/edges-20190219-perlayer/bert-ba... coref-ontonotes-conll \n", - "6 /nfs/jsalt/exp/edges-20190219-perlayer/bert-ba... coref-ontonotes-conll \n", - "7 /nfs/jsalt/exp/edges-20190219-perlayer/bert-ba... coref-ontonotes-conll \n", - "8 /nfs/jsalt/exp/edges-20190219-perlayer/bert-ba... coref-ontonotes-conll \n", - "9 /nfs/jsalt/exp/edges-20190219-perlayer/bert-ba... coref-ontonotes-conll \n", - "10 /nfs/jsalt/exp/edges-20190219-perlayer/bert-ba... coref-ontonotes-conll \n", - "11 /nfs/jsalt/exp/edges-20190219-perlayer/bert-ba... coref-ontonotes-conll \n", - "12 /nfs/jsalt/exp/edges-20190219-perlayer/bert-ba... coref-ontonotes-conll \n", - "13 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... coref-ontonotes-conll \n", - "14 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... coref-ontonotes-conll \n", - "15 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... coref-ontonotes-conll \n", - "16 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... coref-ontonotes-conll \n", - "17 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... coref-ontonotes-conll \n", - "18 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... coref-ontonotes-conll \n", - "19 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... coref-ontonotes-conll \n", - "20 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... coref-ontonotes-conll \n", - "21 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... coref-ontonotes-conll \n", - "22 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... coref-ontonotes-conll \n", - "23 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... coref-ontonotes-conll \n", - "24 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... coref-ontonotes-conll \n", - "25 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... coref-ontonotes-conll \n", - "26 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... coref-ontonotes-conll \n", - "27 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... coref-ontonotes-conll \n", - "28 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... coref-ontonotes-conll \n", - "29 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... coref-ontonotes-conll \n", - ".. ... ... \n", - "388 /nfs/jsalt/exp/edges-20190219-perlayer/bert-ba... srl-conll2012 \n", - "389 /nfs/jsalt/exp/edges-20190219-perlayer/bert-ba... srl-conll2012 \n", - "390 /nfs/jsalt/exp/edges-20190219-perlayer/bert-ba... srl-conll2012 \n", - "391 /nfs/jsalt/exp/edges-20190219-perlayer/bert-ba... srl-conll2012 \n", - "392 /nfs/jsalt/exp/edges-20190219-perlayer/bert-ba... srl-conll2012 \n", - "393 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... srl-conll2012 \n", - "394 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... srl-conll2012 \n", - "395 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... srl-conll2012 \n", - "396 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... srl-conll2012 \n", - "397 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... srl-conll2012 \n", - "398 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... srl-conll2012 \n", - "399 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... srl-conll2012 \n", - "400 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... srl-conll2012 \n", - "401 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... srl-conll2012 \n", - "402 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... srl-conll2012 \n", - "403 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... srl-conll2012 \n", - "404 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... srl-conll2012 \n", - "405 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... srl-conll2012 \n", - "406 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... srl-conll2012 \n", - "407 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... srl-conll2012 \n", - "408 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... srl-conll2012 \n", - "409 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... srl-conll2012 \n", - "410 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... srl-conll2012 \n", - "411 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... srl-conll2012 \n", - "412 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... srl-conll2012 \n", - "413 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... srl-conll2012 \n", - "414 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... srl-conll2012 \n", - "415 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... srl-conll2012 \n", - "416 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... srl-conll2012 \n", - "417 /nfs/jsalt/exp/edges-20190219-perlayer/bert-la... srl-conll2012 \n", - "\n", - " ... lex_score prev_layer_score delta_score exp_layer \\\n", - "0 ... 0.800073 0 0.800073 3.61864 \n", - "1 ... 0.800073 0.800072 0.0251754 3.61864 \n", - "2 ... 0.800073 0.825248 0.0177116 3.61864 \n", - "3 ... 0.800073 0.84296 0.0089664 3.61864 \n", - "4 ... 0.800073 0.851926 0.0174738 3.61864 \n", - "5 ... 0.800073 0.8694 0.00642173 3.61864 \n", - "6 ... 0.800073 0.875822 0.00700518 3.61864 \n", - "7 ... 0.800073 0.882827 0.00610089 3.61864 \n", - "8 ... 0.800073 0.888928 0.0138143 3.61864 \n", - "9 ... 0.800073 0.902742 0.00106283 3.61864 \n", - "10 ... 0.800073 0.903805 0.00185246 3.61864 \n", - "11 ... 0.800073 0.905657 -0.00283255 3.61864 \n", - "12 ... 0.800073 0.902825 -0.00117671 3.61864 \n", - "13 ... 0.804676 0 0.804676 9.47118 \n", - "14 ... 0.804676 0.804676 0.0138794 9.47118 \n", - "15 ... 0.804676 0.818555 0.00465181 9.47118 \n", - "16 ... 0.804676 0.823207 0.00199498 9.47118 \n", - "17 ... 0.804676 0.825202 0.0129732 9.47118 \n", - "18 ... 0.804676 0.838175 0.00353595 9.47118 \n", - "19 ... 0.804676 0.841711 -0.000370241 9.47118 \n", - "20 ... 0.804676 0.841341 0.00385491 9.47118 \n", - "21 ... 0.804676 0.845196 0.00762873 9.47118 \n", - "22 ... 0.804676 0.852824 0.00320275 9.47118 \n", - "23 ... 0.804676 0.856027 0.00683303 9.47118 \n", - "24 ... 0.804676 0.86286 0.0105196 9.47118 \n", - "25 ... 0.804676 0.87338 0.00151244 9.47118 \n", - "26 ... 0.804676 0.874892 0.0104718 9.47118 \n", - "27 ... 0.804676 0.885364 0.00669758 9.47118 \n", - "28 ... 0.804676 0.892062 0.0109588 9.47118 \n", - "29 ... 0.804676 0.90302 0.00442688 9.47118 \n", - ".. ... ... ... ... ... \n", - "388 ... 0.794559 0.910484 -0.000485895 2.58844 \n", - "389 ... 0.794559 0.909998 -0.00284303 2.58844 \n", - "390 ... 0.794559 0.907155 -0.00249621 2.58844 \n", - "391 ... 0.794559 0.904659 0.00373638 2.58844 \n", - "392 ... 0.794559 0.908396 0.00248999 2.58844 \n", - "393 ... 0.813187 0 0.813187 6.53665 \n", - "394 ... 0.813187 0.813187 0.004584 6.53665 \n", - "395 ... 0.813187 0.817771 0.0325581 6.53665 \n", - "396 ... 0.813187 0.850329 -0.0175545 6.53665 \n", - "397 ... 0.813187 0.832774 0.0287785 6.53665 \n", - "398 ... 0.813187 0.861553 0.00160226 6.53665 \n", - "399 ... 0.813187 0.863155 0.000765017 6.53665 \n", - "400 ... 0.813187 0.86392 0.00830327 6.53665 \n", - "401 ... 0.813187 0.872223 0.0118061 6.53665 \n", - "402 ... 0.813187 0.884029 -0.00446198 6.53665 \n", - "403 ... 0.813187 0.879567 0.00832321 6.53665 \n", - "404 ... 0.813187 0.887891 0.0119102 6.53665 \n", - "405 ... 0.813187 0.899801 0.00145596 6.53665 \n", - "406 ... 0.813187 0.901257 0.00799423 6.53665 \n", - "407 ... 0.813187 0.909251 0.00411436 6.53665 \n", - "408 ... 0.813187 0.913365 -0.000362014 6.53665 \n", - "409 ... 0.813187 0.913003 0.00307592 6.53665 \n", - "410 ... 0.813187 0.916079 -0.00146085 6.53665 \n", - "411 ... 0.813187 0.914618 -0.00214778 6.53665 \n", - "412 ... 0.813187 0.912471 0.00202615 6.53665 \n", - "413 ... 0.813187 0.914497 0.00222463 6.53665 \n", - "414 ... 0.813187 0.916721 -5.3509e-06 6.53665 \n", - "415 ... 0.813187 0.916716 -0.00212719 6.53665 \n", - "416 ... 0.813187 0.914589 0.00180863 6.53665 \n", - "417 ... 0.813187 0.916397 -0.001931 6.53665 \n", - "\n", - " prev_score_max real_delta_score kl_unif contextual_headroom \\\n", - "0 0.000000 0.800073 0.632103 0.105585 \n", - "1 0.800072 0.0251754 0.632103 0.105585 \n", - "2 0.825248 0.0177116 0.632103 0.105585 \n", - "3 0.842960 0.0089664 0.632103 0.105585 \n", - "4 0.851926 0.0174738 0.632103 0.105585 \n", - "5 0.869400 0.00642173 0.632103 0.105585 \n", - "6 0.875822 0.00700518 0.632103 0.105585 \n", - "7 0.882827 0.00610089 0.632103 0.105585 \n", - "8 0.888928 0.0138143 0.632103 0.105585 \n", - "9 0.902742 0.00106283 0.632103 0.105585 \n", - "10 0.903805 0.00185246 0.632103 0.105585 \n", - "11 0.905657 -0.00283255 0.632103 0.105585 \n", - "12 0.905657 -0.00117671 0.632103 0.105585 \n", - "13 0.000000 0.804676 0.598248 0.116391 \n", - "14 0.804676 0.0138794 0.598248 0.116391 \n", - "15 0.818555 0.00465181 0.598248 0.116391 \n", - "16 0.823207 0.00199498 0.598248 0.116391 \n", - "17 0.825202 0.0129732 0.598248 0.116391 \n", - "18 0.838175 0.00353595 0.598248 0.116391 \n", - "19 0.841711 -0.000370241 0.598248 0.116391 \n", - "20 0.841711 0.00385491 0.598248 0.116391 \n", - "21 0.845196 0.00762873 0.598248 0.116391 \n", - "22 0.852824 0.00320275 0.598248 0.116391 \n", - "23 0.856027 0.00683303 0.598248 0.116391 \n", - "24 0.862860 0.0105196 0.598248 0.116391 \n", - "25 0.873380 0.00151244 0.598248 0.116391 \n", - "26 0.874892 0.0104718 0.598248 0.116391 \n", - "27 0.885364 0.00669758 0.598248 0.116391 \n", - "28 0.892062 0.0109588 0.598248 0.116391 \n", - "29 0.903020 0.00442688 0.598248 0.116391 \n", - ".. ... ... ... ... \n", - "388 0.910484 -0.000485895 1.210460 0.116326 \n", - "389 0.910484 -0.00284303 1.210460 0.116326 \n", - "390 0.910484 -0.00249621 1.210460 0.116326 \n", - "391 0.910484 0.00373638 1.210460 0.116326 \n", - "392 0.910484 0.00248999 1.210460 0.116326 \n", - "393 0.000000 0.813187 1.307057 0.103535 \n", - "394 0.813187 0.004584 1.307057 0.103535 \n", - "395 0.817771 0.0325581 1.307057 0.103535 \n", - "396 0.850329 -0.0175545 1.307057 0.103535 \n", - "397 0.850329 0.0287785 1.307057 0.103535 \n", - "398 0.861553 0.00160226 1.307057 0.103535 \n", - "399 0.863155 0.000765017 1.307057 0.103535 \n", - "400 0.863920 0.00830327 1.307057 0.103535 \n", - "401 0.872223 0.0118061 1.307057 0.103535 \n", - "402 0.884029 -0.00446198 1.307057 0.103535 \n", - "403 0.884029 0.00832321 1.307057 0.103535 \n", - "404 0.887891 0.0119102 1.307057 0.103535 \n", - "405 0.899801 0.00145596 1.307057 0.103535 \n", - "406 0.901257 0.00799423 1.307057 0.103535 \n", - "407 0.909251 0.00411436 1.307057 0.103535 \n", - "408 0.913365 -0.000362014 1.307057 0.103535 \n", - "409 0.913365 0.00307592 1.307057 0.103535 \n", - "410 0.916079 -0.00146085 1.307057 0.103535 \n", - "411 0.916079 -0.00214778 1.307057 0.103535 \n", - "412 0.916079 0.00202615 1.307057 0.103535 \n", - "413 0.916079 0.00222463 1.307057 0.103535 \n", - "414 0.916721 -5.3509e-06 1.307057 0.103535 \n", - "415 0.916721 -0.00212719 1.307057 0.103535 \n", - "416 0.916721 0.00180863 1.307057 0.103535 \n", - "417 0.916721 -0.001931 1.307057 0.103535 \n", - "\n", - " headroom_frac real_headroom_frac \n", - "0 7.57755 7.57755 \n", - "1 0.238438 0.238438 \n", - "2 0.167748 0.167748 \n", - "3 0.0849214 0.0849214 \n", - "4 0.165496 0.165496 \n", - "5 0.0608207 0.0608207 \n", - "6 0.0663466 0.0663466 \n", - "7 0.057782 0.057782 \n", - "8 0.130836 0.130836 \n", - "9 0.0100661 0.0100661 \n", - "10 0.0175448 0.0175448 \n", - "11 -0.0268273 -0.0268273 \n", - "12 -0.0111447 -0.0111447 \n", - "13 6.91358 6.91358 \n", - "14 0.119249 0.119249 \n", - "15 0.0399672 0.0399672 \n", - "16 0.0171404 0.0171404 \n", - "17 0.111463 0.111463 \n", - "18 0.0303801 0.0303801 \n", - "19 -0.00318102 -0.00318102 \n", - "20 0.0331205 0.0331205 \n", - "21 0.0655442 0.0655442 \n", - "22 0.0275172 0.0275172 \n", - "23 0.0587078 0.0587078 \n", - "24 0.0903819 0.0903819 \n", - "25 0.0129945 0.0129945 \n", - "26 0.0899712 0.0899712 \n", - "27 0.0575441 0.0575441 \n", - "28 0.0941554 0.0941554 \n", - "29 0.0380347 0.0380347 \n", - ".. ... ... \n", - "388 -0.00417701 -0.00417701 \n", - "389 -0.0244402 -0.0244402 \n", - "390 -0.0214587 -0.0214587 \n", - "391 0.0321199 0.0321199 \n", - "392 0.0214053 0.0214053 \n", - "393 7.85424 7.85424 \n", - "394 0.044275 0.044275 \n", - "395 0.314466 0.314466 \n", - "396 -0.169552 -0.169552 \n", - "397 0.27796 0.27796 \n", - "398 0.0154756 0.0154756 \n", - "399 0.00738899 0.00738899 \n", - "400 0.080198 0.080198 \n", - "401 0.11403 0.11403 \n", - "402 -0.0430965 -0.0430965 \n", - "403 0.0803906 0.0803906 \n", - "404 0.115035 0.115035 \n", - "405 0.0140625 0.0140625 \n", - "406 0.077213 0.077213 \n", - "407 0.039739 0.039739 \n", - "408 -0.00349654 -0.00349654 \n", - "409 0.029709 0.029709 \n", - "410 -0.0141097 -0.0141097 \n", - "411 -0.0207446 -0.0207446 \n", - "412 0.0195698 0.0195698 \n", - "413 0.0214868 0.0214868 \n", - "414 -5.16822e-05 -5.16822e-05 \n", - "415 -0.0205456 -0.0205456 \n", - "416 0.0174688 0.0174688 \n", - "417 -0.0186507 -0.0186507 \n", - "\n", - "[418 rows x 43 columns]" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "EXPECTED_NUM_LAYERS = {13, 25}\n", - "USE_RUNNING_MAX = False\n", - "# USE_RUNNING_MAX = True\n", - "\n", - "def _compute_exp_layer(sub_df, min_layer):\n", - " sub_df = sub_df[sub_df['layer_num'].map(int) >= min_layer]\n", - "# ds = sub_df['delta_score'].map(lambda s: max(s, 0))\n", - " ds = sub_df['delta_score']\n", - " num = np.sum(ds * sub_df['layer_num'].map(int))\n", - " denom = np.sum(ds)\n", - " return num / denom\n", - "\n", - "# entropy(scalars[i], qk=masks[i], base=2)\n", - "def _compute_kl_unif(sub_df, min_layer):\n", - " sub_df = sub_df[sub_df['layer_num'].map(int) >= min_layer]\n", - " ds = sub_df['delta_score'].map(lambda s: max(s, 0))\n", - " return entropy(ds.values, qk=np.ones_like(ds.values), base=2)\n", - "\n", - "fdf['max_layer_score'] = None\n", - "fdf['lex_score'] = None\n", - "fdf['prev_layer_score'] = None\n", - "fdf['delta_score'] = None\n", - "fdf['exp_layer'] = None\n", - "gb = fdf.groupby(by=['display_row', 'exp_type', 'tag'])\n", - "for key, idxs in gb.groups.items():\n", - " if len(idxs) not in EXPECTED_NUM_LAYERS:\n", - " print(f\"Warning: key '{key}' has {len(idxs)} matches (expected {EXPECTED_NUM_LAYERS})\")\n", - " sub_df = fdf.loc[idxs]\n", - " layer_nums = sub_df['layer_num'].map(int)\n", - " max_layer = layer_nums.max()\n", - " assert set(layer_nums.map(int)) == set(range(max_layer+1))\n", - " layer_scores = np.zeros(max_layer+1, dtype=np.float32)\n", - " for i, score in zip(layer_nums, sub_df['score']):\n", - " layer_scores[i] = score\n", - " running_max_layer_scores = np.maximum.accumulate(layer_scores)\n", - " fdf.loc[idxs, 'prev_layer_score'] = [layer_scores[i-1] if i > 0 else 0.0 for i in layer_nums]\n", - " fdf.loc[idxs, 'prev_score_max'] = [running_max_layer_scores[i-1] if i > 0 else 0.0 for i in layer_nums]\n", - " if USE_RUNNING_MAX:\n", - " fdf.loc[idxs, 'delta_score'] = running_max_layer_scores - fdf.loc[idxs, 'prev_score_max']\n", - " else:\n", - " fdf.loc[idxs, 'delta_score'] = fdf.loc[idxs, 'score'] - fdf.loc[idxs, 'prev_layer_score']\n", - " fdf.loc[idxs, 'real_delta_score'] = fdf.loc[idxs, 'score'] - fdf.loc[idxs, 'prev_layer_score']\n", - " sub_df = fdf.loc[idxs]\n", - " fdf.loc[idxs, 'exp_layer'] = _compute_exp_layer(sub_df, min_layer=1)\n", - " fdf.loc[idxs, 'kl_unif'] = _compute_kl_unif(sub_df, min_layer=1)\n", - " fdf.loc[idxs, 'max_layer_score'] = sub_df['score'].max()\n", - " fdf.loc[idxs, 'lex_score'] = sub_df[layer_nums == 0]['score'].max()\n", - " fdf.loc[idxs, 'contextual_headroom'] = fdf.loc[idxs, 'max_layer_score'] - fdf.loc[idxs, 'lex_score']\n", - " fdf.loc[idxs, 'headroom_frac'] = fdf.loc[idxs, 'delta_score'] / fdf.loc[idxs, 'contextual_headroom']\n", - " fdf.loc[idxs, 'real_headroom_frac'] = fdf.loc[idxs, 'real_delta_score'] / fdf.loc[idxs, 'contextual_headroom']\n", - "fdf" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": { - "scrolled": false - }, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": [ - "(function(root) {\n", - " function embed_document(root) {\n", - " \n", - " var docs_json = {\"a6e7f150-9b9c-4530-8529-3c73dcfc2965\":{\"roots\":{\"references\":[{\"attributes\":{\"below\":[{\"id\":\"1012\",\"type\":\"LinearAxis\"}],\"left\":[{\"id\":\"1017\",\"type\":\"CategoricalAxis\"}],\"plot_height\":80,\"plot_width\":800,\"renderers\":[{\"id\":\"1012\",\"type\":\"LinearAxis\"},{\"id\":\"1016\",\"type\":\"Grid\"},{\"id\":\"1017\",\"type\":\"CategoricalAxis\"},{\"id\":\"1020\",\"type\":\"Grid\"},{\"id\":\"1029\",\"type\":\"GlyphRenderer\"},{\"id\":\"1035\",\"type\":\"GlyphRenderer\"},{\"id\":\"1041\",\"type\":\"GlyphRenderer\"},{\"id\":\"1047\",\"type\":\"GlyphRenderer\"},{\"id\":\"1051\",\"type\":\"LabelSet\"}],\"title\":{\"id\":\"1057\",\"type\":\"Title\"},\"toolbar\":{\"id\":\"1022\",\"type\":\"Toolbar\"},\"x_range\":{\"id\":\"1005\",\"type\":\"Range1d\"},\"x_scale\":{\"id\":\"1008\",\"type\":\"LinearScale\"},\"y_range\":{\"id\":\"1003\",\"type\":\"FactorRange\"},\"y_scale\":{\"id\":\"1010\",\"type\":\"CategoricalScale\"}},\"id\":\"1004\",\"subtype\":\"Figure\",\"type\":\"Plot\"},{\"attributes\":{\"callback\":null,\"data\":{\"_bar_center\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"_bar_height\":[],\"_display_name\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"_fill_color\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"_formatted_exp_layer\":[],\"_formatted_score\":[],\"_line_color\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"accuracy\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"accuracy_errn95\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"contextual_headroom\":[],\"delta_score\":[],\"display_col\":[],\"display_row\":[],\"exp_layer\":[],\"exp_name\":[],\"exp_type\":[],\"f1_errn95\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"f1_score\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"fn_count\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"fp_count\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"headroom_frac\":[],\"index\":[],\"kl_unif\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"label\":[],\"layer_num\":[],\"lex_score\":[],\"max_layer_score\":[],\"num_epochs\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"num_steps\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"precision\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"precision_errn95\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"pred_pos_count\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"prev_layer_score\":[],\"prev_score_max\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"real_delta_score\":[],\"real_headroom_frac\":[],\"recall\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"recall_errn95\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"run\":[],\"score\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"score_errn95\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"seed\":[],\"split\":[],\"stratifier\":[],\"stratum_key\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"tag\":[],\"task\":[],\"tn_count\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"total_count\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"tp_count\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"true_pos_count\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]}},\"selected\":{\"id\":\"1061\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1062\",\"type\":\"UnionRenderers\"}},\"id\":\"1025\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"height\":{\"value\":1.0},\"left\":{\"value\":0.5},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"line_width\":{\"value\":0.5},\"right\":{\"value\":12.5},\"y\":{\"field\":\"_display_name\"}},\"id\":\"1034\",\"type\":\"HBar\"},{\"attributes\":{},\"id\":\"1063\",\"type\":\"Selection\"},{\"attributes\":{\"callback\":null,\"end\":12.5,\"start\":0.5},\"id\":\"1005\",\"type\":\"Range1d\"},{\"attributes\":{\"data_source\":{\"id\":\"1031\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1033\",\"type\":\"HBar\"},\"hover_glyph\":null,\"level\":\"underlay\",\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1034\",\"type\":\"HBar\"},\"selection_glyph\":null,\"view\":{\"id\":\"1036\",\"type\":\"CDSView\"}},\"id\":\"1035\",\"type\":\"GlyphRenderer\"},{\"attributes\":{},\"id\":\"1008\",\"type\":\"LinearScale\"},{\"attributes\":{\"ticks\":[0,1,2,3,4,5,6,7,8,9,10,11,12]},\"id\":\"1053\",\"type\":\"FixedTicker\"},{\"attributes\":{\"plot\":{\"id\":\"1004\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"source\":{\"id\":\"1050\",\"type\":\"ColumnDataSource\"},\"text\":{\"field\":\"_formatted_score\"},\"text_align\":\"center\",\"text_color\":{\"value\":\"White\"},\"text_font_size\":{\"value\":\"12pt\"},\"x\":{\"field\":\"layer_num\"},\"y\":{\"field\":\"_display_name\",\"transform\":{\"id\":\"1049\",\"type\":\"Dodge\"}},\"y_offset\":{\"value\":5}},\"id\":\"1051\",\"type\":\"LabelSet\"},{\"attributes\":{\"source\":{\"id\":\"1031\",\"type\":\"ColumnDataSource\"}},\"id\":\"1036\",\"type\":\"CDSView\"},{\"attributes\":{},\"id\":\"1061\",\"type\":\"Selection\"},{\"attributes\":{},\"id\":\"1010\",\"type\":\"CategoricalScale\"},{\"attributes\":{\"callback\":null,\"data\":{\"_bar_center\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"_bar_height\":[],\"_display_name\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"_fill_color\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"_formatted_exp_layer\":[],\"_formatted_score\":[],\"_line_color\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"accuracy\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"accuracy_errn95\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"contextual_headroom\":[],\"delta_score\":[],\"display_col\":[],\"display_row\":[],\"exp_layer\":[],\"exp_name\":[],\"exp_type\":[],\"f1_errn95\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"f1_score\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"fn_count\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"fp_count\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"headroom_frac\":[],\"index\":[],\"kl_unif\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"label\":[],\"layer_num\":[],\"lex_score\":[],\"max_layer_score\":[],\"num_epochs\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"num_steps\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"precision\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"precision_errn95\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"pred_pos_count\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"prev_layer_score\":[],\"prev_score_max\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"real_delta_score\":[],\"real_headroom_frac\":[],\"recall\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"recall_errn95\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"run\":[],\"score\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"score_errn95\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"seed\":[],\"split\":[],\"stratifier\":[],\"stratum_key\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"tag\":[],\"task\":[],\"tn_count\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"total_count\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"tp_count\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"true_pos_count\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]}},\"selected\":{\"id\":\"1067\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1068\",\"type\":\"UnionRenderers\"}},\"id\":\"1043\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"axis_label\":\"Encoder Layer\",\"axis_label_text_font_size\":{\"value\":\"13pt\"},\"formatter\":{\"id\":\"1060\",\"type\":\"BasicTickFormatter\"},\"major_label_text_font_size\":{\"value\":\"13pt\"},\"plot\":{\"id\":\"1004\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"ticker\":{\"id\":\"1053\",\"type\":\"FixedTicker\"}},\"id\":\"1012\",\"type\":\"LinearAxis\"},{\"attributes\":{\"callback\":null,\"data\":{\"_bar_center\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"_bar_height\":[],\"_display_name\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"_fill_color\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"_formatted_exp_layer\":[],\"_formatted_score\":[],\"_line_color\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"accuracy\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"accuracy_errn95\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"contextual_headroom\":[],\"delta_score\":[],\"display_col\":[],\"display_row\":[],\"exp_layer\":[],\"exp_name\":[],\"exp_type\":[],\"f1_errn95\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"f1_score\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"fn_count\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"fp_count\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"headroom_frac\":[],\"index\":[],\"kl_unif\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"label\":[],\"layer_num\":[],\"lex_score\":[],\"max_layer_score\":[],\"num_epochs\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"num_steps\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"precision\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"precision_errn95\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"pred_pos_count\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"prev_layer_score\":[],\"prev_score_max\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"real_delta_score\":[],\"real_headroom_frac\":[],\"recall\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"recall_errn95\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"run\":[],\"score\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"score_errn95\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"seed\":[],\"split\":[],\"stratifier\":[],\"stratum_key\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"tag\":[],\"task\":[],\"tn_count\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"total_count\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"tp_count\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"true_pos_count\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]}},\"selected\":{\"id\":\"1069\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1070\",\"type\":\"UnionRenderers\"}},\"id\":\"1050\",\"type\":\"ColumnDataSource\"},{\"attributes\":{},\"id\":\"1064\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"range\":{\"id\":\"1003\",\"type\":\"FactorRange\"},\"value\":-0.5},\"id\":\"1049\",\"type\":\"Dodge\"},{\"attributes\":{},\"id\":\"1065\",\"type\":\"Selection\"},{\"attributes\":{\"plot\":{\"id\":\"1004\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"ticker\":{\"id\":\"1053\",\"type\":\"FixedTicker\"}},\"id\":\"1016\",\"type\":\"Grid\"},{\"attributes\":{},\"id\":\"1066\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"source\":{\"id\":\"1043\",\"type\":\"ColumnDataSource\"}},\"id\":\"1048\",\"type\":\"CDSView\"},{\"attributes\":{\"formatter\":{\"id\":\"1058\",\"type\":\"CategoricalTickFormatter\"},\"major_label_text_font_size\":{\"value\":\"13pt\"},\"plot\":{\"id\":\"1004\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"ticker\":{\"id\":\"1018\",\"type\":\"CategoricalTicker\"}},\"id\":\"1017\",\"type\":\"CategoricalAxis\"},{\"attributes\":{},\"id\":\"1067\",\"type\":\"Selection\"},{\"attributes\":{\"data_source\":{\"id\":\"1043\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1045\",\"type\":\"Rect\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1046\",\"type\":\"Rect\"},\"selection_glyph\":null,\"view\":{\"id\":\"1048\",\"type\":\"CDSView\"}},\"id\":\"1047\",\"type\":\"GlyphRenderer\"},{\"attributes\":{},\"id\":\"1018\",\"type\":\"CategoricalTicker\"},{\"attributes\":{\"source\":{\"id\":\"1037\",\"type\":\"ColumnDataSource\"}},\"id\":\"1042\",\"type\":\"CDSView\"},{\"attributes\":{},\"id\":\"1068\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"height\":{\"units\":\"data\",\"value\":1.0},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"width\":{\"units\":\"data\",\"value\":0.9},\"x\":{\"field\":\"layer_num\"},\"y\":{\"field\":\"_bar_center\"}},\"id\":\"1046\",\"type\":\"Rect\"},{\"attributes\":{\"callback\":null,\"factor_padding\":0.2},\"id\":\"1003\",\"type\":\"FactorRange\"},{\"attributes\":{\"dimension\":1,\"plot\":{\"id\":\"1004\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"ticker\":{\"id\":\"1055\",\"type\":\"FixedTicker\"}},\"id\":\"1020\",\"type\":\"Grid\"},{\"attributes\":{\"data_source\":{\"id\":\"1037\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1039\",\"type\":\"Rect\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1040\",\"type\":\"Rect\"},\"selection_glyph\":null,\"view\":{\"id\":\"1042\",\"type\":\"CDSView\"}},\"id\":\"1041\",\"type\":\"GlyphRenderer\"},{\"attributes\":{},\"id\":\"1069\",\"type\":\"Selection\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.0},\"fill_color\":{\"value\":\"#1f77b4\"},\"height\":{\"units\":\"data\",\"value\":1.0},\"line_alpha\":{\"value\":0.0},\"line_color\":{\"value\":\"#1f77b4\"},\"width\":{\"units\":\"data\",\"value\":0.9},\"x\":{\"field\":\"layer_num\"},\"y\":{\"field\":\"_bar_center\"}},\"id\":\"1045\",\"type\":\"Rect\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"height\":{\"value\":1.0},\"left\":{\"value\":0.5},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"right\":{\"value\":12.5},\"y\":{\"field\":\"_display_name\"}},\"id\":\"1028\",\"type\":\"HBar\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"height\":{\"field\":\"_bar_height\",\"units\":\"data\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"width\":{\"units\":\"data\",\"value\":0.9},\"x\":{\"field\":\"layer_num\"},\"y\":{\"field\":\"_bar_center\"}},\"id\":\"1040\",\"type\":\"Rect\"},{\"attributes\":{},\"id\":\"1070\",\"type\":\"UnionRenderers\"},{\"attributes\":{},\"id\":\"1062\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"active_drag\":\"auto\",\"active_inspect\":\"auto\",\"active_multi\":null,\"active_scroll\":\"auto\",\"active_tap\":\"auto\",\"tools\":[{\"id\":\"1002\",\"type\":\"HoverTool\"},{\"id\":\"1021\",\"type\":\"SaveTool\"}]},\"id\":\"1022\",\"type\":\"Toolbar\"},{\"attributes\":{\"callback\":null,\"data\":{\"_bar_center\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"_bar_height\":[],\"_display_name\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"_fill_color\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"_formatted_exp_layer\":[],\"_formatted_score\":[],\"_line_color\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"accuracy\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"accuracy_errn95\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"contextual_headroom\":[],\"delta_score\":[],\"display_col\":[],\"display_row\":[],\"exp_layer\":[],\"exp_name\":[],\"exp_type\":[],\"f1_errn95\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"f1_score\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"fn_count\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"fp_count\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"headroom_frac\":[],\"index\":[],\"kl_unif\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"label\":[],\"layer_num\":[],\"lex_score\":[],\"max_layer_score\":[],\"num_epochs\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"num_steps\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"precision\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"precision_errn95\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"pred_pos_count\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"prev_layer_score\":[],\"prev_score_max\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"real_delta_score\":[],\"real_headroom_frac\":[],\"recall\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"recall_errn95\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"run\":[],\"score\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"score_errn95\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"seed\":[],\"split\":[],\"stratifier\":[],\"stratum_key\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"tag\":[],\"task\":[],\"tn_count\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"total_count\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"tp_count\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"true_pos_count\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]}},\"selected\":{\"id\":\"1065\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1066\",\"type\":\"UnionRenderers\"}},\"id\":\"1037\",\"type\":\"ColumnDataSource\"},{\"attributes\":{},\"id\":\"1021\",\"type\":\"SaveTool\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.4},\"fill_color\":{\"value\":\"#f2f2f2\"},\"height\":{\"value\":1.0},\"left\":{\"value\":0.5},\"line_alpha\":{\"value\":0.0},\"line_color\":{\"value\":\"#1f77b4\"},\"right\":{\"value\":12.5},\"y\":{\"field\":\"_display_name\"}},\"id\":\"1027\",\"type\":\"HBar\"},{\"attributes\":{\"callback\":null,\"data\":{\"_bar_center\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"_bar_height\":[],\"_display_name\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"_fill_color\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"_formatted_exp_layer\":[],\"_formatted_score\":[],\"_line_color\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"accuracy\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"accuracy_errn95\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"contextual_headroom\":[],\"delta_score\":[],\"display_col\":[],\"display_row\":[],\"exp_layer\":[],\"exp_name\":[],\"exp_type\":[],\"f1_errn95\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"f1_score\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"fn_count\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"fp_count\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"headroom_frac\":[],\"index\":[],\"kl_unif\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"label\":[],\"layer_num\":[],\"lex_score\":[],\"max_layer_score\":[],\"num_epochs\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"num_steps\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"precision\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"precision_errn95\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"pred_pos_count\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"prev_layer_score\":[],\"prev_score_max\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"real_delta_score\":[],\"real_headroom_frac\":[],\"recall\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"recall_errn95\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"run\":[],\"score\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"score_errn95\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"seed\":[],\"split\":[],\"stratifier\":[],\"stratum_key\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"tag\":[],\"task\":[],\"tn_count\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"total_count\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"tp_count\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"true_pos_count\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]}},\"selected\":{\"id\":\"1063\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1064\",\"type\":\"UnionRenderers\"}},\"id\":\"1031\",\"type\":\"ColumnDataSource\"},{\"attributes\":{},\"id\":\"1060\",\"type\":\"BasicTickFormatter\"},{\"attributes\":{},\"id\":\"1058\",\"type\":\"CategoricalTickFormatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.0},\"fill_color\":{\"value\":\"White\"},\"height\":{\"value\":1.0},\"left\":{\"value\":0.5},\"line_color\":{\"value\":\"#e6e6e6\"},\"line_width\":{\"value\":0.5},\"right\":{\"value\":12.5},\"y\":{\"field\":\"_display_name\"}},\"id\":\"1033\",\"type\":\"HBar\"},{\"attributes\":{\"plot\":null,\"text\":\"\"},\"id\":\"1057\",\"type\":\"Title\"},{\"attributes\":{\"fill_color\":{\"field\":\"_fill_color\"},\"height\":{\"field\":\"_bar_height\",\"units\":\"data\"},\"line_color\":{\"field\":\"_line_color\"},\"width\":{\"units\":\"data\",\"value\":0.9},\"x\":{\"field\":\"layer_num\"},\"y\":{\"field\":\"_bar_center\"}},\"id\":\"1039\",\"type\":\"Rect\"},{\"attributes\":{\"data_source\":{\"id\":\"1025\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1027\",\"type\":\"HBar\"},\"hover_glyph\":null,\"level\":\"image\",\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1028\",\"type\":\"HBar\"},\"selection_glyph\":null,\"view\":{\"id\":\"1030\",\"type\":\"CDSView\"}},\"id\":\"1029\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"callback\":null,\"renderers\":[{\"id\":\"1041\",\"type\":\"GlyphRenderer\"},{\"id\":\"1047\",\"type\":\"GlyphRenderer\"}],\"tooltips\":[[\"task\",\"@_display_name\"],[\"layer\",\"@layer_num\"],[\"score\",\"@score{0.00} (\\u0394 @delta_score{0.00})\"]]},\"id\":\"1002\",\"type\":\"HoverTool\"},{\"attributes\":{\"ticks\":[]},\"id\":\"1055\",\"type\":\"FixedTicker\"},{\"attributes\":{\"source\":{\"id\":\"1025\",\"type\":\"ColumnDataSource\"}},\"id\":\"1030\",\"type\":\"CDSView\"}],\"root_ids\":[\"1004\"]},\"title\":\"Bokeh Application\",\"version\":\"1.0.4\"}};\n", - " var render_items = [{\"docid\":\"a6e7f150-9b9c-4530-8529-3c73dcfc2965\",\"roots\":{\"1004\":\"c582de0c-3973-4d23-bbf6-48d5abac1759\"}}];\n", - " root.Bokeh.embed.embed_items_notebook(docs_json, render_items);\n", - "\n", - " }\n", - " if (root.Bokeh !== undefined) {\n", - " embed_document(root);\n", - " } else {\n", - " var attempts = 0;\n", - " var timer = setInterval(function(root) {\n", - " if (root.Bokeh !== undefined) {\n", - " embed_document(root);\n", - " clearInterval(timer);\n", - " }\n", - " attempts++;\n", - " if (attempts > 100) {\n", - " console.log(\"Bokeh: ERROR: Unable to run BokehJS code because BokehJS library is missing\");\n", - " clearInterval(timer);\n", - " }\n", - " }, 10, root)\n", - " }\n", - "})(window);" - ], - "application/vnd.bokehjs_exec.v0+json": "" - }, - "metadata": { - "application/vnd.bokehjs_exec.v0+json": { - "id": "1004" - } - }, - "output_type": "display_data" - } - ], - "source": [ - "palette = bokeh.palettes.Category20c_20\n", - "\n", - "# EXPT_TYPE = \"bert-base-uncased-mix\"\n", - "# EXPT_TYPE = \"bert-large-uncased-mix\"\n", - "EXPT_TYPE = \"bert-base-uncased-at\"\n", - "MAX_LAYER = 24 if \"-large-\" in EXPT_TYPE else 12\n", - "BAR_SCALE = 1.2\n", - "COLORS = (palette[0], palette[0]) # blues\n", - "COLORS = (palette[12], palette[12]) # purples\n", - "NEG_COLORS = (palette[5], palette[4]) # oranges\n", - "PLOT_WIDTH = 800\n", - "\n", - "##\n", - "# Don't change below here\n", - "##\n", - "def _make_display_name(task, label):\n", - " if task.startswith(\"pos-\"):\n", - " return \"POS\"\n", - " elif task.startswith(\"coref-\"):\n", - " return \"Coref.\"\n", - " elif task.startswith(\"srl\"):\n", - " return \"SRL\"\n", - " elif task.startswith(\"spr\"):\n", - " return \"SPR\"\n", - " elif task.startswith(\"rel-\"):\n", - " return \"Relations\"\n", - " elif task.startswith(\"dep-\"):\n", - " return \"Deps.\"\n", - " elif task.startswith(\"nonterminal-\"):\n", - " return \"Consts.\"\n", - " else:\n", - " return analysis.make_display_name(task, label) \n", - "\n", - "mask = fdf['exp_type'] == EXPT_TYPE\n", - "mask &= fdf['layer_num'].notnull()\n", - "mask &= fdf['task'] != 'constituent-ontonotes' # don't use this task\n", - "mask &= fdf['task'] != 'ner-tacred' # don't use this task\n", - "mask &= fdf['task'] != 'coref-gap' # don't use this task\n", - "mask &= fdf['task'] != 'coref-gap-ontonotes' # don't use this task\n", - "mask &= fdf['task'] != 'noun-verb' # don't use this task\n", - "mask &= fdf['task'] != 'dpr' # don't use this task- noisy\n", - "## Skip these for now\n", - "mask &= fdf['task'] != 'rel-tacred' # don't use this task\n", - "# mask &= fdf['task'] != 'rel-semeval' # don't use this task\n", - "# mask &= fdf['task'] != 'spr1' # don't use this task- noisy\n", - "mask &= fdf['task'] != 'spr2' # don't use this task- noisy\n", - "## TEMPORARY\n", - "# mask &= fdf['task'] == \"dep-labeling-ewt\" # TEMPORARY\n", - "\n", - "# ELMo models also have 'scalar_mix_0.', which is for pretraining and not used by edge probing.\n", - "# mask &= df['scalar_set'].map(lambda s: s.endswith(\"scalar_mix.\") or s.endswith(\"scalar_mix_1.\"))\n", - "plot_df = fdf[mask].copy()\n", - "\n", - "##\n", - "# Make long-form DataFrame\n", - "plot_df['_display_name'] = list(map(_make_display_name, plot_df['task'], plot_df['label']))\n", - "# plot_df['_display_name'] = plot_df['display_row']\n", - "\n", - "# plot_df['_bar_height'] = plot_df['score'] * BAR_SCALE\n", - "# plot_df['_bar_height'] = list(map(lambda low, high, s: BAR_SCALE * (s - low)/max(high - low, 0.025), \n", - "# plot_df['lex_score'], plot_df['max_layer_score'], plot_df['score']))\n", - "# plot_df['_bar_height'] = plot_df['real_headroom_frac'].map(lambda s: BAR_SCALE * s)\n", - "plot_df['_bar_height'] = (plot_df['score'] - plot_df['lex_score']) / (plot_df['max_layer_score'] - plot_df['lex_score'])\n", - "\n", - "plot_df['_bar_center'] = [(l, h/2-0.5) for l, h in zip(plot_df['_display_name'], plot_df['_bar_height'])]\n", - "# plot_df['_bar_center'] = [(l, 0) for l, h in zip(plot_df['_display_name'], plot_df['_bar_height'])]\n", - "\n", - "plot_df['_fill_color'] = [COLORS[0] if h > 0 else NEG_COLORS[0] for h in plot_df['_bar_height']]\n", - "plot_df['_line_color'] = [COLORS[1] if h > 0 else NEG_COLORS[1] for h in plot_df['_bar_height']]\n", - "plot_df['_bar_height'] = plot_df['_bar_height'].map(np.abs)\n", - "\n", - "plot_df['_formatted_exp_layer'] = plot_df['exp_layer'].map(lambda l: \"E[layer] = {:.02f}\".format(l))\n", - "plot_df['_formatted_score'] = plot_df['score'].map(lambda l: \"{:.1f}\".format(100*l))\n", - "\n", - "# sorted_rows = sorted(plot_df['display_row'].unique(), key=task_sort_key)\n", - "# cats = list(reversed(sorted_rows))\n", - "sorted_rows = sorted(pd.Series(list(zip(plot_df['task'], plot_df['label']))).unique(), \n", - " key=lambda tl: (task_sort_key(tl[0]), tl[1]))\n", - "cats = [_make_display_name(*tl) for tl in reversed(sorted_rows)]\n", - "\n", - "hover = bokeh.models.HoverTool(\n", - " tooltips=[\n", - " (\"task\", \"@_display_name\"),\n", - " (\"layer\", \"@layer_num\"),\n", - " (\"score\", \"@score{0.00} (Δ @delta_score{0.00})\"),\n", - " ],\n", - " renderers=[]\n", - ")\n", - "\n", - "x_range = (0.5, MAX_LAYER+0.5)\n", - "# PLOT_WIDTH = 700 if MAX_LAYER > 2 else 300\n", - "PLOT_HEIGHT = 80 + 80*len(cats)\n", - "p = bp.figure(y_range=bokeh.models.FactorRange(*cats, factor_padding=0.20), x_range=x_range,\n", - " plot_width=PLOT_WIDTH, plot_height=PLOT_HEIGHT, tools=[hover, 'save'])\n", - "\n", - "##\n", - "# Add background bars\n", - "bgbar_color = \"#f2f2f2\"\n", - "p.hbar(y='_display_name', left=x_range[0], right=x_range[1], \n", - " height=1.0, \n", - " fill_color=bgbar_color, fill_alpha=0.40, \n", - "# line_color=\"#e6e6e6\", \n", - "# line_alpha=0.80,\n", - "# line_color=\"Gray\",\n", - " line_alpha=0.0,\n", - "# line_width=0.5,\n", - " source=plot_df, \n", - " level='image')\n", - "p.hbar(y='_display_name', left=x_range[0], right=x_range[1], \n", - " height=1.0, \n", - " fill_color=\"White\", fill_alpha=0.0,\n", - " line_color=\"#e6e6e6\",\n", - " line_alpha=1.0,\n", - " line_width=0.5,\n", - " source=plot_df, \n", - " level='underlay')\n", - "\n", - "bars = p.rect(x='layer_num', y='_bar_center', width=0.9, height=\"_bar_height\",\n", - " fill_color='_fill_color', line_color='_line_color',\n", - " source=plot_df)\n", - "# Add an invisible overlay for easier tooltips on small bars\n", - "shadow_bars = p.rect(x='layer_num', y='_bar_center', width=0.9, height=1.0,\n", - " source=plot_df, alpha=0.0)\n", - "hover.renderers.extend([bars, shadow_bars])\n", - "\n", - "# Add score labels\n", - "y = bokeh.transform.dodge(\"_display_name\", -0.5, range=p.y_range)\n", - "score_labels = bokeh.models.annotations.LabelSet(\n", - " y=y, x=\"layer_num\", text=\"_formatted_score\",\n", - " y_offset=5, text_align=\"center\", text_baseline=\"bottom\",\n", - " text_color=\"White\", text_font_size=\"12pt\", \n", - " source=bokeh.models.ColumnDataSource(plot_df))\n", - "p.add_layout(score_labels)\n", - "\n", - "# Add labels with entropy\n", - "# score_labels = bokeh.models.annotations.LabelSet(\n", - "# y=\"_display_name\", x=MAX_LAYER, text=\"_formatted_exp_layer\",\n", - "# text_align=\"right\", text_baseline=\"middle\", y_offset=-15,\n", - "# x_offset=8,\n", - "# text_color=COLORS[0], text_font_size=\"11pt\",\n", - "# text_font_style=\"bold\",\n", - "# background_fill_color=\"White\", border_line_color=\"White\", border_line_width=5,\n", - "# source=bokeh.models.ColumnDataSource(plot_df[plot_df['layer_num'].map(int) == 0]))\n", - "# p.add_layout(score_labels)\n", - "\n", - "p.xaxis.ticker = bokeh.models.FixedTicker(ticks=np.arange(0, MAX_LAYER+1))\n", - "p.xgrid.ticker = p.xaxis[0].ticker\n", - "\n", - "p.ygrid.ticker = bokeh.models.FixedTicker(ticks=np.arange(0, len(cats), 0.5))\n", - " \n", - "_FONT_SIZE = \"13pt\"\n", - "p.yaxis.major_label_text_font_size = _FONT_SIZE\n", - "p.xaxis.major_label_text_font_size = _FONT_SIZE\n", - "p.xaxis.axis_label = \"Encoder Layer\"\n", - "p.xaxis.axis_label_text_font_size = _FONT_SIZE\n", - "\n", - "bp.show(p)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Extract mixing scalars" - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "metadata": { - "scrolled": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "['coref-ontonotes-conll' 'dep-labeling-ewt' 'dpr' 'ner-ontonotes'\n", - " 'nonterminal-ontonotes' 'pos-ontonotes' 'rel-semeval' 'rel-tacred' 'spr1'\n", - " 'spr2' 'srl-conll2012' 'constituent-ontonotes']\n", - "['bert-base-uncased-mix' 'bert-base-uncased-mix-pre'\n", - " 'bert-large-uncased-mix' 'bert-large-uncased-mix-pre' 'elmo-full'\n", - " 'elmo-ortho']\n", - "58\n", - "Scalar sets: ['sent_encoder._text_field_embedder.scalar_mix.'\n", - " 'sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.']\n" - ] - } - ], - "source": [ - "def load_scalars_file(filename, tag=None):\n", - " df = pd.read_csv(filename, sep=\"\\t\", header=0)\n", - " df.drop(['Unnamed: 0'], axis='columns', inplace=True)\n", - " \n", - " df.insert(0, \"exp_name\", df['run'].map(lambda p: os.path.basename(os.path.dirname(p.strip(\"/\")))))\n", - " df.insert(1, \"exp_type\", df['exp_name'].map(analysis.get_exp_type))\n", - " df.insert(2, \"task\", df['exp_name'].map(lambda name: analysis.clean_task_name(name.split(\"-edges-\")[1])))\n", - " if tag is not None:\n", - " df.insert(0, \"tag\", tag)\n", - " \n", - " return df\n", - "\n", - "scalar_files = [\n", - " (\"base\", \"/nfs/jsalt/exp/edges-20190217-mix-pre/scalars.tsv\"),\n", - " (\"base\", \"/nfs/jsalt/exp/edges-20190218-mix-pre/scalars.tsv\"),\n", - " # ELMo plot for camera-ready\n", - " (\"base\", \"/nfs/jsalt/home/iftenney/exp/final_20180927/base/scalars.tsv\"),\n", - " # Comment this out for re-creating paper plots, otherwise get duplicate rows which\n", - " # screw up the plot formatting.\n", - " (\"base\", \"/nfs/jsalt/exp/edges-20190205-semeval/scalars.tsv\"),\n", - "]\n", - "\n", - "dfs = []\n", - "for tag, scalar_file in scalar_files:\n", - " dfs.append(load_scalars_file(scalar_file, tag=tag))\n", - "scalar_df = pd.concat(dfs, ignore_index=True, sort=False)\n", - "scalar_df['display_col'] = [\"%s (%s)\" % et for et in zip(scalar_df.exp_type, scalar_df.tag)]\n", - "# ELMo models also have 'scalar_mix_0.', which is for pretraining and not used by edge probing.\n", - "mask = scalar_df['scalar_set'].map(lambda s: s.endswith(\"scalar_mix.\") or s.endswith(\"scalar_mix_1.\"))\n", - "scalar_df = scalar_df[mask].copy()\n", - "print(scalar_df['task'].unique())\n", - "print(scalar_df['exp_type'].unique())\n", - "print(len(scalar_df))\n", - "print(\"Scalar sets:\", scalar_df['scalar_set'].unique())" - ] - }, - { - "cell_type": "code", - "execution_count": 29, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Index(['tag', 'exp_name', 'exp_type', 'task', 'checkpoint', 'gamma', 'label',\n", - " 'run', 'scalar_parameters.0', 'scalar_parameters.1',\n", - " 'scalar_parameters.10', 'scalar_parameters.11', 'scalar_parameters.12',\n", - " 'scalar_parameters.2', 'scalar_parameters.3', 'scalar_parameters.4',\n", - " 'scalar_parameters.5', 'scalar_parameters.6', 'scalar_parameters.7',\n", - " 'scalar_parameters.8', 'scalar_parameters.9', 'scalar_set',\n", - " 'scalar_parameters.13', 'scalar_parameters.14', 'scalar_parameters.15',\n", - " 'scalar_parameters.16', 'scalar_parameters.17', 'scalar_parameters.18',\n", - " 'scalar_parameters.19', 'scalar_parameters.20', 'scalar_parameters.21',\n", - " 'scalar_parameters.22', 'scalar_parameters.23', 'scalar_parameters.24',\n", - " 'display_col'],\n", - " dtype='object')\n" - ] - } - ], - "source": [ - "print(scalar_df.columns)" - ] - }, - { - "cell_type": "code", - "execution_count": 30, - "metadata": { - "scrolled": true - }, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
tagexp_nameexp_typetaskcheckpointgammalabelrunscalar_parameters.0scalar_parameters.1...192021222324weight_entropyweight_kl_unifweight_exp_layerweight_exp_layer_oneplus
0basebert-base-uncased-mix-edges-coref-ontonotes-conllbert-base-uncased-mixcoref-ontonotes-conll/model_state_eval_best.th1.682971__scalar_mix__/nfs/jsalt/exp/edges-20190217-mix-pre/bert-bas...-0.630028-0.761247...0000003.291324.091179e-017.9621188.214730
1basebert-base-uncased-mix-edges-dep-labeling-ewtbert-base-uncased-mixdep-labeling-ewt/model_state_eval_best.th3.026450__scalar_mix__/nfs/jsalt/exp/edges-20190217-mix-pre/bert-bas...-0.324348-0.365665...0000003.102525.979175e-016.5480906.716994
2basebert-base-uncased-mix-edges-dprbert-base-uncased-mixdpr/model_state_eval_best.th0.996561__scalar_mix__/nfs/jsalt/exp/edges-20190217-mix-pre/bert-bas...-0.001596-0.000428...0000003.700446.778836e-076.0025426.501843
3basebert-base-uncased-mix-edges-ner-ontonotesbert-base-uncased-mixner-ontonotes/model_state_eval_best.th2.208929__scalar_mix__/nfs/jsalt/exp/edges-20190217-mix-pre/bert-bas...-0.221502-0.218776...0000003.587591.128481e-016.8627067.276716
4basebert-base-uncased-mix-edges-nonterminal-ontonotesbert-base-uncased-mixnonterminal-ontonotes/model_state_eval_best.th2.014895__scalar_mix__/nfs/jsalt/exp/edges-20190217-mix-pre/bert-bas...-0.521184-0.483713...0000003.273544.269024e-016.0063786.193607
\n", - "

5 rows × 64 columns

\n", - "
" - ], - "text/plain": [ - " tag exp_name \\\n", - "0 base bert-base-uncased-mix-edges-coref-ontonotes-conll \n", - "1 base bert-base-uncased-mix-edges-dep-labeling-ewt \n", - "2 base bert-base-uncased-mix-edges-dpr \n", - "3 base bert-base-uncased-mix-edges-ner-ontonotes \n", - "4 base bert-base-uncased-mix-edges-nonterminal-ontonotes \n", - "\n", - " exp_type task checkpoint \\\n", - "0 bert-base-uncased-mix coref-ontonotes-conll /model_state_eval_best.th \n", - "1 bert-base-uncased-mix dep-labeling-ewt /model_state_eval_best.th \n", - "2 bert-base-uncased-mix dpr /model_state_eval_best.th \n", - "3 bert-base-uncased-mix ner-ontonotes /model_state_eval_best.th \n", - "4 bert-base-uncased-mix nonterminal-ontonotes /model_state_eval_best.th \n", - "\n", - " gamma label \\\n", - "0 1.682971 __scalar_mix__ \n", - "1 3.026450 __scalar_mix__ \n", - "2 0.996561 __scalar_mix__ \n", - "3 2.208929 __scalar_mix__ \n", - "4 2.014895 __scalar_mix__ \n", - "\n", - " run scalar_parameters.0 \\\n", - "0 /nfs/jsalt/exp/edges-20190217-mix-pre/bert-bas... -0.630028 \n", - "1 /nfs/jsalt/exp/edges-20190217-mix-pre/bert-bas... -0.324348 \n", - "2 /nfs/jsalt/exp/edges-20190217-mix-pre/bert-bas... -0.001596 \n", - "3 /nfs/jsalt/exp/edges-20190217-mix-pre/bert-bas... -0.221502 \n", - "4 /nfs/jsalt/exp/edges-20190217-mix-pre/bert-bas... -0.521184 \n", - "\n", - " scalar_parameters.1 ... 19 20 21 22 23 24 \\\n", - "0 -0.761247 ... 0 0 0 0 0 0 \n", - "1 -0.365665 ... 0 0 0 0 0 0 \n", - "2 -0.000428 ... 0 0 0 0 0 0 \n", - "3 -0.218776 ... 0 0 0 0 0 0 \n", - "4 -0.483713 ... 0 0 0 0 0 0 \n", - "\n", - " weight_entropy weight_kl_unif weight_exp_layer weight_exp_layer_oneplus \n", - "0 3.29132 4.091179e-01 7.962118 8.214730 \n", - "1 3.10252 5.979175e-01 6.548090 6.716994 \n", - "2 3.70044 6.778836e-07 6.002542 6.501843 \n", - "3 3.58759 1.128481e-01 6.862706 7.276716 \n", - "4 3.27354 4.269024e-01 6.006378 6.193607 \n", - "\n", - "[5 rows x 64 columns]" - ] - }, - "execution_count": 30, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Count total scalar columns\n", - "scalar_columns = collections.OrderedDict(sorted(\n", - " [(int(m.group(1)), m.group(0)) for m in \n", - " (re.match(\"^scalar_parameters\\.(\\d+)$\", str(name)) for name in scalar_df.columns)\n", - " if m]\n", - "))\n", - "\n", - "# Fill NaN with -inf for scalar columns\n", - "for name in scalar_columns.values():\n", - " scalar_df[name].fillna(value=-np.inf, inplace=True)\n", - "\n", - "# Pre-fill number columns\n", - "for number in scalar_columns.keys():\n", - " scalar_df[number] = None\n", - "scalar_df[\"weight_entropy\"] = None\n", - " \n", - "# Softmax over parameters in each row\n", - "num_scalars = max(scalar_columns.keys()) + 1\n", - "scalars = {}\n", - "masks = {}\n", - "for i, row in scalar_df.iterrows():\n", - " arr = np.zeros(num_scalars, dtype=np.float32)\n", - " for j, col in scalar_columns.items():\n", - " arr[j] = float(row[col])\n", - " if np.isnan(arr[j]):\n", - " arr[j] = -np.inf\n", - " # Softmax over row\n", - " scalars[i] = softmax(arr)\n", - " masks[i] = np.isfinite(arr)\n", - "\n", - "# Add softmax weights back to DataFrame, with numeric column names.\n", - "# This way, we can convert to long-form for easy plotting.\n", - "for i in scalar_df.index:\n", - " for j in scalar_columns.keys():\n", - " scalar_df.loc[i, j] = scalars[i][j]\n", - " # Compute entropy\n", - " scalar_df.loc[i, \"weight_entropy\"] = entropy(scalars[i], base=2)\n", - " scalar_df.loc[i, \"weight_kl_unif\"] = entropy(scalars[i], qk=masks[i], base=2)\n", - " # Compute expectation\n", - " weighted_layers = scalars[i] * np.arange(len(scalars[i])) * masks[i]\n", - " scalar_df.loc[i, \"weight_exp_layer\"] = np.sum(weighted_layers)\n", - " scalar_df.loc[i, \"weight_exp_layer_oneplus\"] = np.sum(weighted_layers[1:]) / np.sum(scalars[i][1:] * masks[i][1:])\n", - "\n", - "scalar_df.head()" - ] - }, - { - "cell_type": "code", - "execution_count": 41, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array(['bert-base-uncased-mix', 'bert-base-uncased-mix-pre',\n", - " 'bert-large-uncased-mix', 'bert-large-uncased-mix-pre',\n", - " 'elmo-full', 'elmo-ortho'], dtype=object)" - ] - }, - "execution_count": 41, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "scalar_df.exp_type.unique()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Make compound plot with F1 scores as well" - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "metadata": { - "scrolled": false - }, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/usr/share/anaconda3/lib/python3.6/site-packages/bokeh/plotting/helpers.py:591: UserWarning: HoverTool are being repeated\n", - " warnings.warn(\"%s are being repeated\" % \",\".join(repeated_tools))\n" - ] - }, - { - "data": { - "text/html": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": [ - "(function(root) {\n", - " function embed_document(root) {\n", - " \n", - " var docs_json = {\"a0d84aec-43c1-44fb-af19-4abe86c671d6\":{\"roots\":{\"references\":[{\"attributes\":{\"below\":[{\"id\":\"3207\",\"type\":\"LinearAxis\"}],\"left\":[{\"id\":\"3212\",\"type\":\"CategoricalAxis\"}],\"min_border_bottom\":0,\"min_border_left\":0,\"min_border_right\":0,\"min_border_top\":0,\"plot_height\":750,\"plot_width\":450,\"renderers\":[{\"id\":\"3207\",\"type\":\"LinearAxis\"},{\"id\":\"3211\",\"type\":\"Grid\"},{\"id\":\"3212\",\"type\":\"CategoricalAxis\"},{\"id\":\"3215\",\"type\":\"Grid\"},{\"id\":\"3225\",\"type\":\"GlyphRenderer\"},{\"id\":\"3231\",\"type\":\"GlyphRenderer\"},{\"id\":\"3239\",\"type\":\"GlyphRenderer\"},{\"id\":\"3245\",\"type\":\"GlyphRenderer\"},{\"id\":\"3253\",\"type\":\"GlyphRenderer\"},{\"id\":\"3259\",\"type\":\"GlyphRenderer\"},{\"id\":\"3265\",\"type\":\"LabelSet\"},{\"id\":\"3268\",\"type\":\"LabelSet\"}],\"title\":{\"id\":\"3370\",\"type\":\"Title\"},\"toolbar\":{\"id\":\"3217\",\"type\":\"Toolbar\"},\"toolbar_location\":null,\"x_range\":{\"id\":\"3200\",\"type\":\"Range1d\"},\"x_scale\":{\"id\":\"3203\",\"type\":\"LinearScale\"},\"y_range\":{\"id\":\"3198\",\"type\":\"FactorRange\"},\"y_scale\":{\"id\":\"3205\",\"type\":\"CategoricalScale\"}},\"id\":\"3199\",\"subtype\":\"Figure\",\"type\":\"Plot\"},{\"attributes\":{},\"id\":\"3381\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"source\":{\"id\":\"3221\",\"type\":\"ColumnDataSource\"}},\"id\":\"3226\",\"type\":\"CDSView\"},{\"attributes\":{\"callback\":null,\"data\":{\"_bar_center\":[\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\"],\"_bar_height\":[0.04494346976280213,0.04006913993507624,0.09287066906690598,0.0376878110691905,0.12816421128809452,0.09434745647013187,0.09976273588836193,0.06169388685375452,0.1017415925860405,0.04303781222552061,0.02665954409167171,0.092449951171875,0.030033160373568537,0.09519200026988983,0.0938491590321064,0.09799955897033215,0.05106540396809578,0.09109024219214917,0.044170017912983896,0.022351319622248414,0.08779376037418843,0.028858571592718364,0.07931437566876412,0.09353651739656926,0.09733275510370731,0.04365954492241145,0.0903110269457102,0.041819173190742735,0.025936662778258325,0.08510068506002427,0.029954698216170073,0.07533357851207256,0.09359927102923393,0.09677075855433942,0.04482156839221716,0.0901101429015398,0.03978559691458941,0.03480054046958685,0.07972162552177907,0.03098505372181535,0.06407867074012757,0.09469664990901948,0.09599633105099202,0.05054207649081946,0.09214825294911862,0.039017561450600625,0.038755980692803865,0.08183977436274291,0.030400400888174774,0.07222927026450635,0.09456777311861515,0.09492500312626362,0.054807588458061225,0.09116704724729062,0.03884538123384118,0.03700121752917767,0.08249406069517136,0.027693530637770893,0.0798001253977418,0.09401903338730336,0.09416523054242135,0.054352310299873356,0.08928837105631829,0.039486486185342076,0.02885133465752006,0.08797116838395597,0.030837863311171533,0.0809585077688098,0.09326150380074978,0.09388232119381429,0.04014560049399734,0.08832156881690026,0.03723419001325965,0.022521498240530492,0.08459334522485734,0.026859324239194394,0.07777618244290352,0.09274786747992039,0.09313415586948395,0.037022236827760936,0.08767789900302887,0.042273543588817124,0.018642216827720406,0.08229774814099074,0.03603771440684796,0.10015535093843937,0.09161568693816663,0.09128147028386593,0.03910883283242583,0.08522950150072575,0.04314245861023665,0.031788645219057804,0.07591128610074521,0.08341848738491536,0.11223619468510151,0.09220453910529613,0.09183554090559483,0.048697145842015746,0.0853905949741602,0.05216716825962067,0.11127796210348607,0.08471080586314202,0.24229259043931964,0.24783563017845156,0.09807938151061535,0.09389873631298543,0.08801243752241135,0.09033758081495763,0.06673061773180962,0.2567683316767216,0.08984680697321892,0.40822096019983295,0.2583534970879555,0.10338723845779896,0.09994269870221616,0.12581427432596684,0.09767241328954697,0.0768482705578208,0.4794349774718285,0.10167832598090172,0.5156459659337997,0.28137193992733955,0.10756293497979642,0.10925409458577634,0.32394714653491974,0.10553485304117204,0.0860912248492241,0.3546902909874916,0.12427419014275075,0.2829314567148686,0.1633545655757189,0.11223207078874112,0.11903460882604124,0.35821877717971806,0.11251056455075742,0.11384665668010713,0.22998050674796106,0.14578848704695702,0.22092887610197068,0.10071831308305264,0.12188248112797738,0.12420923374593258,0.2813253901898861,0.12405379302799703,0.2083232916891575,0.46487810611724856,0.16749810576438906,0.26806456893682484,0.10851157195866108,0.13009082525968552,0.12688109613955023,0.2898755148053169,0.13753882348537447,0.2577830716967583,0.17829358130693437,0.16354098580777646,0.12527223341166974,0.08917633183300495,0.1320855036377907,0.12739758901298048,0.19218101352453232,0.14197779558598997,0.35319715887308123,0.06741776447743178,0.15761889964342118,0.04084996450692416,0.07334743961691857,0.13149371445178987,0.12683158926665783,0.14120552055537702,0.14144478701055052,0.3369572952389717,0.04757114611566067,0.16487951204180717,0.03264276450499892,0.07273645419627428,0.13116803728044035,0.127137703076005,0.089138925075531,0.14031972773373128,0.3319104708731175,0.039260345790535216,0.15436116233468056,0.03534103492274881,0.06885472107678653,0.12991811446845533,0.12614560425281526,0.06290892250835896,0.13668489530682565,0.13514871373772622,0.02999556250870228,0.12364344522356988,0.03050988279283047,0.05796121247112752,0.12565156146883966,0.1222495883703232,0.05130967944860459,0.1297759607434273,0.09033160619437695,0.03306763647124172,0.10747762061655522,0.03593307808041573,0.06231307480484247,0.12103274725377561,0.12066990472376347,0.05398421231657267,0.12235910296440125,0.07643184754997492,0.0395142118446529,0.09810982793569566,0.03995051253587008,0.06900277398526669,0.11493384651839735,0.11653186641633512,0.0593707200139761,0.1144467942416668,0.06047666352242232,0.04047167748212815,0.08352814782410861,0.028649495076388122,0.08122366424649954,0.11203573308885098,0.11272982507944108,0.05679134856909514,0.11286671832203866],\"_display_name\":[\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\"],\"_formatted_entropy\":[\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\"],\"_formatted_kl_unif\":[\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\"],\"checkpoint\":[\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\"],\"display_col\":[\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\"],\"exp_name\":[\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\"],\"exp_type\":[\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\"],\"gamma\":{\"__ndarray__\":\"AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/\",\"dtype\":\"float64\",\"shape\":[225]},\"index\":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224],\"label\":[\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\"],\"layer_num\":[0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8,8,9,9,9,9,9,9,9,9,9,10,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,12,13,13,13,13,13,13,13,13,13,14,14,14,14,14,14,14,14,14,15,15,15,15,15,15,15,15,15,16,16,16,16,16,16,16,16,16,17,17,17,17,17,17,17,17,17,18,18,18,18,18,18,18,18,18,19,19,19,19,19,19,19,19,19,20,20,20,20,20,20,20,20,20,21,21,21,21,21,21,21,21,21,22,22,22,22,22,22,22,22,22,23,23,23,23,23,23,23,23,23,24,24,24,24,24,24,24,24,24],\"layer_weight\":[0.016645729541778564,0.014840422198176384,0.034396544098854065,0.01395844854414463,0.04746822640299797,0.03494350239634514,0.03694916144013405,0.022849587723612785,0.03768207132816315,0.015939930453896523,0.009873905219137669,0.03424072265625,0.01112339273095131,0.03525629639625549,0.03475894778966904,0.03629613295197487,0.018913112580776215,0.03373712673783302,0.01635926589369774,0.00827826652675867,0.03251620754599571,0.01068835984915495,0.029375694692134857,0.034643154591321945,0.036049168556928635,0.01617020182311535,0.03344852849841118,0.015488582663238049,0.009606171399354935,0.03151877224445343,0.011094332672655582,0.02790132537484169,0.03466639667749405,0.035841021686792374,0.016600580886006355,0.0333741270005703,0.014735406264662743,0.012889089062809944,0.02952652797102928,0.011475945822894573,0.02373284101486206,0.03507283329963684,0.0355541966855526,0.01871928758919239,0.034128982573747635,0.014450948685407639,0.014354066923260689,0.03031102754175663,0.011259407736361027,0.026751581579446793,0.03502510115504265,0.03515740856528282,0.02029910683631897,0.03376557305455208,0.014387178234755993,0.013704154640436172,0.030553355813026428,0.010256863199174404,0.029555601999163628,0.03482186421751976,0.034876011312007904,0.02013048529624939,0.03306976705789566,0.014624624513089657,0.010685679502785206,0.032581914216279984,0.011421430855989456,0.02998463250696659,0.0345412977039814,0.034771230071783066,0.014868740923702717,0.0327116921544075,0.013790440745651722,0.008341295644640923,0.03133086860179901,0.009947897866368294,0.028805993497371674,0.03435106202960014,0.03449413180351257,0.013711939565837383,0.03247329592704773,0.015656867995858192,0.006904524751007557,0.030480647459626198,0.013347301632165909,0.03709457442164421,0.03393173590302467,0.03380795195698738,0.014484752900898457,0.03156648203730583,0.01597868837416172,0.01177357230335474,0.02811529114842415,0.030895736068487167,0.04156896099448204,0.03414982929825783,0.034013163298368454,0.018035979941487312,0.031626146286726,0.019321173429489136,0.04121406003832817,0.03137437254190445,0.08973799645900726,0.09179097414016724,0.03632569685578346,0.034777309745550156,0.03259719908237457,0.03345836326479912,0.024715043604373932,0.09509938210248947,0.033276595175266266,0.15119294822216034,0.09568648040294647,0.0382915697991848,0.03701581433415413,0.04659787937998772,0.036174967885017395,0.028462322428822517,0.17756851017475128,0.03765863925218582,0.1909799873828888,0.10421182960271835,0.03983812406659126,0.040464479476213455,0.11998042464256287,0.03908698260784149,0.03188563883304596,0.1313667744398117,0.04602747783064842,0.10478942841291428,0.060501690953969955,0.04156743362545967,0.044086892157793045,0.13267362117767334,0.041670579463243484,0.04216542840003967,0.0851779654622078,0.05399573594331741,0.08182550966739655,0.037303078919649124,0.045141659677028656,0.046003419905900955,0.10419458895921707,0.045945849269628525,0.07715677469968796,0.17217707633972168,0.062036335468292236,0.09928317368030548,0.0401894710958004,0.04818178713321686,0.04699299857020378,0.10736130177974701,0.05094030499458313,0.0954752117395401,0.06603465974330902,0.06057073548436165,0.046397123485803604,0.03302827104926109,0.04892055690288544,0.0471842922270298,0.07117815315723419,0.052584368735551834,0.13081376254558563,0.024969542399048805,0.05837737023830414,0.015129616484045982,0.027165718376636505,0.04870137572288513,0.04697466269135475,0.05229834094643593,0.05238695815205574,0.12479899823665619,0.017618943005800247,0.061066485941410065,0.01208991277962923,0.026939427480101585,0.048580754548311234,0.04708803817629814,0.03301441669464111,0.05197026953101158,0.12292980402708054,0.014540868811309338,0.0571708008646965,0.013089272193610668,0.02550174854695797,0.04811782017350197,0.04672059416770935,0.023299600929021835,0.05062403529882431,0.05005507916212082,0.011109467595815659,0.045793868601322174,0.01129995658993721,0.021467115730047226,0.0465376153588295,0.04527762532234192,0.01900358498096466,0.048065170645713806,0.03345615044236183,0.01224727276712656,0.03980652615427971,0.01330854743719101,0.0230789165943861,0.044826943427324295,0.04469255730509758,0.019994152709841728,0.04531818628311157,0.028308091685175896,0.014634893275797367,0.03633697330951691,0.014796486124396324,0.02555658295750618,0.04256809130311012,0.04315995052456856,0.021989155560731888,0.0423877015709877,0.02239876426756382,0.014989510178565979,0.03093635104596615,0.01061092410236597,0.030082838609814644,0.041494715958833694,0.041751787066459656,0.02103383280336857,0.04180248826742172],\"run\":[\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\"],\"scalar_set\":[\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\"],\"tag\":[\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\"],\"task\":[\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\"],\"weight_entropy\":[4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481],\"weight_exp_layer\":{\"__ndarray__\":\"AABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipA\",\"dtype\":\"float64\",\"shape\":[225]},\"weight_exp_layer_oneplus\":{\"__ndarray__\":\"SG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytA\",\"dtype\":\"float64\",\"shape\":[225]},\"weight_kl_unif\":{\"__ndarray__\":\"w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/\",\"dtype\":\"float64\",\"shape\":[225]}},\"selected\":{\"id\":\"3376\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"3377\",\"type\":\"UnionRenderers\"}},\"id\":\"3227\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"data_source\":{\"id\":\"3255\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"3257\",\"type\":\"Rect\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"3258\",\"type\":\"Rect\"},\"selection_glyph\":null,\"view\":{\"id\":\"3260\",\"type\":\"CDSView\"}},\"id\":\"3259\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"source\":{\"id\":\"3255\",\"type\":\"ColumnDataSource\"}},\"id\":\"3260\",\"type\":\"CDSView\"},{\"attributes\":{},\"id\":\"3380\",\"type\":\"Selection\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"height\":{\"field\":\"_bar_height\",\"units\":\"data\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"width\":{\"units\":\"data\",\"value\":0.9},\"x\":{\"field\":\"layer_num\"},\"y\":{\"field\":\"_bar_center\",\"transform\":{\"id\":\"3233\",\"type\":\"Dodge\"}}},\"id\":\"3237\",\"type\":\"Rect\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.0},\"fill_color\":{\"value\":\"White\"},\"height\":{\"value\":1.0},\"left\":{\"value\":-0.5},\"line_color\":{\"value\":\"#e6e6e6\"},\"line_width\":{\"value\":0.5},\"right\":{\"value\":24.5},\"y\":{\"field\":\"_display_name\"}},\"id\":\"3229\",\"type\":\"HBar\"},{\"attributes\":{\"data_source\":{\"id\":\"3227\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"3229\",\"type\":\"HBar\"},\"hover_glyph\":null,\"level\":\"underlay\",\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"3230\",\"type\":\"HBar\"},\"selection_glyph\":null,\"view\":{\"id\":\"3232\",\"type\":\"CDSView\"}},\"id\":\"3231\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"height\":{\"units\":\"data\",\"value\":0.5},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"width\":{\"units\":\"data\",\"value\":0.9},\"x\":{\"field\":\"layer_num\"},\"y\":{\"field\":\"_bar_center\",\"transform\":{\"id\":\"3233\",\"type\":\"Dodge\"}}},\"id\":\"3244\",\"type\":\"Rect\"},{\"attributes\":{},\"id\":\"3379\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"callback\":null,\"end\":24.5,\"start\":-0.5},\"id\":\"3200\",\"type\":\"Range1d\"},{\"attributes\":{},\"id\":\"3216\",\"type\":\"SaveTool\"},{\"attributes\":{\"active_drag\":\"auto\",\"active_inspect\":\"auto\",\"active_multi\":null,\"active_scroll\":\"auto\",\"active_tap\":\"auto\",\"tools\":[{\"id\":\"3196\",\"type\":\"HoverTool\"},{\"id\":\"3197\",\"type\":\"HoverTool\"},{\"id\":\"3216\",\"type\":\"SaveTool\"}]},\"id\":\"3217\",\"type\":\"Toolbar\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"height\":{\"field\":\"_bar_height\",\"units\":\"data\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"line_width\":{\"value\":1.5},\"width\":{\"units\":\"data\",\"value\":0.9},\"x\":{\"field\":\"layer_num\"},\"y\":{\"field\":\"_bar_center\",\"transform\":{\"id\":\"3247\",\"type\":\"Dodge\"}}},\"id\":\"3251\",\"type\":\"Rect\"},{\"attributes\":{},\"id\":\"3378\",\"type\":\"Selection\"},{\"attributes\":{\"plot\":{\"id\":\"3199\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"source\":{\"id\":\"3267\",\"type\":\"ColumnDataSource\"},\"text\":{\"field\":\"_formatted_kl_unif\"},\"text_color\":{\"value\":\"#404040\"},\"text_font_size\":{\"value\":\"12pt\"},\"x\":{\"value\":4.9},\"y\":{\"field\":\"_display_name\"},\"y_offset\":{\"value\":18}},\"id\":\"3268\",\"type\":\"LabelSet\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"height\":{\"value\":1.0},\"left\":{\"value\":-0.5},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"line_width\":{\"value\":0.5},\"right\":{\"value\":24.5},\"y\":{\"field\":\"_display_name\"}},\"id\":\"3230\",\"type\":\"HBar\"},{\"attributes\":{},\"id\":\"3205\",\"type\":\"CategoricalScale\"},{\"attributes\":{\"callback\":null,\"data\":{\"_bar_center\":[[\"Coref.\",0.0],[\"Deps.\",0.0],[\"Entities\",0.0],[\"Consts.\",0.0],[\"POS\",0.0],[\"Relations\",0.0],[\"SPR\",0.0],[\"SRL\",0.0]],\"_bar_height\":{\"__ndarray__\":\"AAAAAAAA8D8AAAAAAADwPwAAAAAAAPA/AAAAAAAA8D8AAAAAAADwPwAAAAAAAPA/AAAAAAAA8D8AAAAAAADwPw==\",\"dtype\":\"float64\",\"shape\":[8]},\"_display_name\":[\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\"],\"_fill_color\":[\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\"],\"_formatted_exp_layer\":[\"9.47\",\"5.69\",\"4.64\",\"3.79\",\"3.39\",\"9.40\",\"9.93\",\"6.54\"],\"_formatted_kl_unif\":[\"K(\\u0394) = 0.60\",\"K(\\u0394) = 1.15\",\"K(\\u0394) = 1.61\",\"K(\\u0394) = 1.57\",\"K(\\u0394) = 1.60\",\"K(\\u0394) = 0.50\",\"K(\\u0394) = 0.33\",\"K(\\u0394) = 1.31\"],\"_line_color\":[\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\"],\"accuracy\":{\"__ndarray__\":\"6gAKtwRX7T+NGpL2UtPvP5w4uTYOsO8/kICAocl87z9Ln1x5c9nvP60HAhZ7BO8/CmbSQvS16z9QxOrSCJzvPw==\",\"dtype\":\"float64\",\"shape\":[8]},\"accuracy_errn95\":{\"__ndarray__\":\"/dwmrP1Qaz+odW0kq+IgP45Ge8IXTjQ/jRely61QFz8ZVpSfStkCP6++xaizQmM/wnJ+hQGzcz9tKFJjUHYiPw==\",\"dtype\":\"float64\",\"shape\":[8]},\"contextual_headroom\":[0.11639055893469108,0.09997559540642187,0.05733773727377656,0.1369172609382292,0.08318042260149905,0.23439707290638978,0.06260312292920267,0.10353468382410691],\"delta_score\":[0.804675649147854,0.8563817514420556,0.905993125093409,0.7355877588962386,0.8851251582672498,0.6072974644403215,0.7766251728907331,0.8131866690279881],\"display_col\":[\"bert-large-uncased-mix-00 (base)\",\"bert-large-uncased-mix-00 (base)\",\"bert-large-uncased-mix-00 (base)\",\"bert-large-uncased-mix-00 (base)\",\"bert-large-uncased-mix-00 (base)\",\"bert-large-uncased-mix-00 (base)\",\"bert-large-uncased-mix-00 (base)\",\"bert-large-uncased-mix-00 (base)\"],\"display_row\":[\"coref-ontonotes-conll-1\",\"dep-labeling-ewt-_micro_avg_\",\"ner-ontonotes-_micro_avg_\",\"nonterminal-ontonotes-_micro_avg_\",\"pos-ontonotes-_micro_avg_\",\"rel-semeval-_clean_micro_\",\"spr1-_micro_avg_\",\"srl-conll2012-_clean_micro_\"],\"exp_layer\":[9.471179711705389,5.691932390197615,4.644666882875676,3.792980575634427,3.386439579545165,9.40046847774628,9.928992732451892,6.536649198760027],\"exp_name\":[\"bert-large-uncased-mix-00-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-00-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-00-edges-ner-ontonotes\",\"bert-large-uncased-mix-00-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-00-edges-pos-ontonotes\",\"bert-large-uncased-mix-00-edges-rel-semeval\",\"bert-large-uncased-mix-00-edges-spr1\",\"bert-large-uncased-mix-00-edges-srl-conll2012\"],\"exp_type\":[\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\"],\"f1_errn95\":{\"__ndarray__\":\"7xGy8kEUhT/Rbxvu/H1xPz+knI4+bHA/BDxIKVt4XD+AEWnUvQxTP5RX8fO5lKA//Raog23khT/KOXv1+v9lPw==\",\"dtype\":\"float64\",\"shape\":[8]},\"f1_score\":{\"__ndarray__\":\"h0ifJee/6T/ttuqzemfrPziqVUvl/ew/TYP5Vu+J5z87/fP+8VLsP37glhf7buM/CR3aCB3a6D+clqAMoAXqPw==\",\"dtype\":\"float64\",\"shape\":[8]},\"fn_count\":{\"__ndarray__\":\"AAAAAABElEAAAAAAAFiyQAAAAAAA8KBAAAAAANCn9EAAAAAA4GHiQAAAAAAAYH1AAAAAAADolkAAAAAAgI3SQA==\",\"dtype\":\"float64\",\"shape\":[8]},\"fp_count\":{\"__ndarray__\":\"AAAAAADgi0AAAAAAAM6gQAAAAAAAGJlAAAAAAMCM4kAAAAAAwDTbQAAAAAAAoGRAAAAAAAB4kUAAAAAAgIXCQA==\",\"dtype\":\"float64\",\"shape\":[8]},\"headroom_frac\":[6.913581793170807,8.56590798945166,15.800991949986932,5.3724983530608466,10.641027426702427,2.5908918439559843,12.405534046105204,7.854243998170655],\"index\":[13,51,127,165,203,241,317,393],\"kl_unif\":{\"__ndarray__\":\"smln+9gk4z9Td0vmwGfyPyr7WHwku/k/1wcJs1Mx+T88bGlG7ob5PyG2W9ubCeA/Zn7/NR5c1T/dCjZNtOn0Pw==\",\"dtype\":\"float64\",\"shape\":[8]},\"label\":[\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\"],\"layer_num\":[\"00\",\"00\",\"00\",\"00\",\"00\",\"00\",\"00\",\"00\"],\"lex_score\":[0.804675649147854,0.8563817514420556,0.905993125093409,0.7355877588962386,0.8851251582672498,0.6072974644403215,0.7766251728907331,0.8131866690279881],\"max_layer_score\":[0.9210662080825451,0.9563573468484775,0.9633308623671856,0.8725050198344678,0.9683055808687488,0.8416945373467113,0.8392282958199357,0.916721352852095],\"num_epochs\":{\"__ndarray__\":\"AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fw==\",\"dtype\":\"float64\",\"shape\":[8]},\"num_steps\":{\"__ndarray__\":\"AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fw==\",\"dtype\":\"float64\",\"shape\":[8]},\"precision\":{\"__ndarray__\":\"7n+9sg236j+Hc4XJGfPsP0AfRepEZ+0/KsK00H4r6j97F1pnlNHsP/QxOB+D8+c/n1lC5XCf6T+UEtMwD8HrPw==\",\"dtype\":\"float64\",\"shape\":[8]},\"precision_errn95\":{\"__ndarray__\":\"vnmb6AdIhD8WeKeAlGNvP52Gxk36KW8/HfEgYSwlWz92Xz5szCZSP62K7XAKAKE/a19aZodohT/Kigtsw19kPw==\",\"dtype\":\"float64\",\"shape\":[8]},\"pred_pos_count\":{\"__ndarray__\":\"AAAAAAAZtUAAAAAAQAnWQAAAAAAAVNNAAAAAADB0CUEAAAAAhBoRQQAAAAAAgIRAAAAAAADqtUAAAAAA8HLxQA==\",\"dtype\":\"float64\",\"shape\":[8]},\"prev_layer_score\":[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0],\"prev_score_max\":{\"__ndarray__\":\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\",\"dtype\":\"float64\",\"shape\":[8]},\"real_delta_score\":[0.804675649147854,0.8563817514420556,0.905993125093409,0.7355877588962386,0.8851251582672498,0.6072974644403215,0.7766251728907331,0.8131866690279881],\"real_headroom_frac\":[6.913581793170807,8.56590798945166,15.800991949986932,5.3724983530608466,10.641027426702427,2.5908918439559843,12.405534046105204,7.854243998170655],\"recall\":{\"__ndarray__\":\"sRhYD/7Z6D/6jLqp9APqP9nCPoFul+w/ZpkQlXBj5T+It1m3ldjrPw+HRbuBWeA/P4Fgv08g6D9Pc2U1Sn7oPw==\",\"dtype\":\"float64\",\"shape\":[8]},\"recall_errn95\":{\"__ndarray__\":\"vOnbYjXxhT8SaILIPsFzP2jnBXAOXHE/iwHXJlnuXT9FsbpXoApUPwgYQbeTLqA/KEy76A5mhj+4XnjOYuhnPw==\",\"dtype\":\"float64\",\"shape\":[8]},\"run\":[\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-00-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-00-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-00-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-00-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-00-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-00-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-00-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-00-edges-srl-conll2012/run\"],\"score\":{\"__ndarray__\":\"h0ifJee/6T/ttuqzemfrPziqVUvl/ew/TYP5Vu+J5z87/fP+8VLsP37glhf7buM/CR3aCB3a6D+clqAMoAXqPw==\",\"dtype\":\"float64\",\"shape\":[8]},\"score_errn95\":{\"__ndarray__\":\"7xGy8kEUhT/Rbxvu/H1xPz+knI4+bHA/BDxIKVt4XD+AEWnUvQxTP5RX8fO5lKA//Raog23khT/KOXv1+v9lPw==\",\"dtype\":\"float64\",\"shape\":[8]},\"seed\":[\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\"],\"split\":[\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\"],\"stratifier\":[\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\"],\"stratum_key\":{\"__ndarray__\":\"AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fw==\",\"dtype\":\"float64\",\"shape\":[8]},\"tag\":[\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\"],\"task\":[\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\"],\"tn_count\":{\"__ndarray__\":\"AAAAAMAs00AAAAAAz70yQQAAAAB4QxZBAAAAwFgUXEEAAAAA+PFpQQAAAAAAGdNAAAAAAADVx0AAAACA1R1BQQ==\",\"dtype\":\"float64\",\"shape\":[8]},\"total_count\":{\"__ndarray__\":\"AAAAAEC32UAAAAAATCgzQQAAAACYmhdBAAAAgJkyXUEAAAAALo1qQQAAAACAMtRAAAAAAIDT0kAAAAAAiM5BQQ==\",\"dtype\":\"float64\",\"shape\":[8]},\"tp_count\":{\"__ndarray__\":\"AAAAAACdsUAAAAAAgO/TQAAAAACAwtFAAAAAAADRBEEAAAAAcM4OQQAAAAAAsH5AAAAAAACMsUAAAAAAgETuQA==\",\"dtype\":\"float64\",\"shape\":[8]},\"true_pos_count\":{\"__ndarray__\":\"AAAAAACutkAAAAAAgIXYQAAAAACA4NNAAAAAAOgkD0EAAAAAdLMRQQAAAAAACI5AAAAAAABGt0AAAAAAoMXzQA==\",\"dtype\":\"float64\",\"shape\":[8]}},\"selected\":{\"id\":\"3388\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"3389\",\"type\":\"UnionRenderers\"}},\"id\":\"3267\",\"type\":\"ColumnDataSource\"},{\"attributes\":{},\"id\":\"3377\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"range\":{\"id\":\"3198\",\"type\":\"FactorRange\"}},\"id\":\"3247\",\"type\":\"Dodge\"},{\"attributes\":{},\"id\":\"3376\",\"type\":\"Selection\"},{\"attributes\":{},\"id\":\"3203\",\"type\":\"LinearScale\"},{\"attributes\":{\"data_source\":{\"id\":\"3221\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"3223\",\"type\":\"HBar\"},\"hover_glyph\":null,\"level\":\"image\",\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"3224\",\"type\":\"HBar\"},\"selection_glyph\":null,\"view\":{\"id\":\"3226\",\"type\":\"CDSView\"}},\"id\":\"3225\",\"type\":\"GlyphRenderer\"},{\"attributes\":{},\"id\":\"3375\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"field\":\"_fill_color\"},\"height\":{\"field\":\"_bar_height\",\"units\":\"data\"},\"line_color\":{\"field\":\"_line_color\"},\"line_width\":{\"value\":1.5},\"width\":{\"units\":\"data\",\"value\":0.9},\"x\":{\"field\":\"layer_num\"},\"y\":{\"field\":\"_bar_center\",\"transform\":{\"id\":\"3247\",\"type\":\"Dodge\"}}},\"id\":\"3250\",\"type\":\"Rect\"},{\"attributes\":{\"plot\":{\"id\":\"3199\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"source\":{\"id\":\"3264\",\"type\":\"ColumnDataSource\"},\"text\":{\"field\":\"_formatted_kl_unif\"},\"text_align\":\"right\",\"text_color\":{\"value\":\"#404040\"},\"text_font_size\":{\"value\":\"12pt\"},\"x\":{\"value\":24.5},\"x_offset\":{\"value\":-10},\"y\":{\"field\":\"_display_name\"},\"y_offset\":{\"value\":18}},\"id\":\"3265\",\"type\":\"LabelSet\"},{\"attributes\":{\"callback\":null,\"data\":{\"_bar_center\":[[\"Coref.\",-0.33901404143352976],[\"Coref.\",-0.446044265972713],[\"Coref.\",-0.4768604307729952],[\"Coref.\",-0.349525558451067],[\"Coref.\",-0.45898692471674774],[\"Coref.\",-0.5042943777232388],[\"Coref.\",-0.455287325332745],[\"Coref.\",-0.411515278184139],[\"Coref.\",-0.46285173750164527],[\"Coref.\",-0.42074447361521033],[\"Coref.\",-0.37798436766717003],[\"Coref.\",-0.4824573791926188],[\"Coref.\",-0.3785389022665467],[\"Coref.\",-0.42231552517488213],[\"Coref.\",-0.37289017134084423],[\"Coref.\",-0.4486531022671646],[\"Coref.\",-0.4257216273924921],[\"Coref.\",-0.430004011498989],[\"Coref.\",-0.49875678241786225],[\"Coref.\",-0.5276814122003841],[\"Coref.\",-0.47584433022688954],[\"Coref.\",-0.48402730887671264],[\"Coref.\",-0.5018934399482096],[\"Coref.\",-0.5175054552404181],[\"Deps.\",-0.15535020398162452],[\"Deps.\",-0.38428250376104167],[\"Deps.\",-0.4047307119398233],[\"Deps.\",-0.25975736407552574],[\"Deps.\",-0.46110204834685437],[\"Deps.\",-0.511350747086902],[\"Deps.\",-0.45352222160719396],[\"Deps.\",-0.4799749446492181],[\"Deps.\",-0.4728940042921681],[\"Deps.\",-0.4058080754182927],[\"Deps.\",-0.3816788121899807],[\"Deps.\",-0.4163178294914107],[\"Deps.\",-0.45435585059051226],[\"Deps.\",-0.44820326706379154],[\"Deps.\",-0.5064172948843114],[\"Deps.\",-0.4665358084766775],[\"Deps.\",-0.5100259102460774],[\"Deps.\",-0.5012581700242449],[\"Deps.\",-0.47643470567042245],[\"Deps.\",-0.5048613661154845],[\"Deps.\",-0.4957281358071249],[\"Deps.\",-0.5114439259885932],[\"Deps.\",-0.5067568946377005],[\"Deps.\",-0.4970990208708064],[\"Entities\",0.0],[\"Entities\",-0.513352993296959],[\"Entities\",-0.45398240786314914],[\"Entities\",-0.3984797211650951],[\"Entities\",-0.3623000265043117],[\"Entities\",-0.5076134742862792],[\"Entities\",-0.44715007418158437],[\"Entities\",-0.4771617602083911],[\"Entities\",-0.47608403699226265],[\"Entities\",-0.46897889679379323],[\"Entities\",-0.3960967010884767],[\"Entities\",-0.4885257724075292],[\"Entities\",-0.4552434783007919],[\"Entities\",-0.4706566887178612],[\"Entities\",-0.4506387386909693],[\"Entities\",-0.4518150528636334],[\"Entities\",-0.5163130279572037],[\"Entities\",-0.47312601139594035],[\"Entities\",-0.4893989751246502],[\"Entities\",-0.5063336345716116],[\"Entities\",-0.523682871717514],[\"Entities\",-0.47614321781526586],[\"Entities\",-0.5036677664611354],[\"Entities\",-0.5345937972945325],[\"Consts.\",0.0],[\"Consts.\",-0.3910621028560085],[\"Consts.\",-0.4538773523447979],[\"Consts.\",-0.23397349936351564],[\"Consts.\",-0.4449021225939842],[\"Consts.\",-0.4932477242812544],[\"Consts.\",-0.5219518560912718],[\"Consts.\",-0.46446696372136126],[\"Consts.\",-0.46371198033184524],[\"Consts.\",-0.423476377463428],[\"Consts.\",-0.4299708940841526],[\"Consts.\",-0.44436975998618633],[\"Consts.\",-0.5110898271055051],[\"Consts.\",-0.5085150777057504],[\"Consts.\",-0.4896168840869088],[\"Consts.\",-0.46871763034956826],[\"Consts.\",-0.5490728892947644],[\"Consts.\",-0.44378345405096703],[\"Consts.\",-0.5113955857757364],[\"Consts.\",-0.49080677516510723],[\"Consts.\",-0.5382438055653194],[\"Consts.\",-0.517638771191431],[\"Consts.\",-0.4803184557172699],[\"Consts.\",-0.49044918351332795],[\"POS\",0.0],[\"POS\",-0.2531556499070403],[\"POS\",-0.4100432150334006],[\"POS\",-0.3366571079776205],[\"POS\",-0.4354764958906403],[\"POS\",-0.4654828795727711],[\"POS\",-0.45107966860845283],[\"POS\",-0.47333985069589174],[\"POS\",-0.4889341328321864],[\"POS\",-0.46936790586023924],[\"POS\",-0.44866724303759253],[\"POS\",-0.46164593910415286],[\"POS\",-0.46702632790348986],[\"POS\",-0.5041049130460499],[\"POS\",-0.5186709460804375],[\"POS\",-0.48451691063275476],[\"POS\",-0.5147313083731214],[\"POS\",-0.4965102318777035],[\"POS\",-0.4903292855078592],[\"POS\",-0.5087608833680461],[\"POS\",-0.5001805209432605],[\"POS\",-0.5019363924931132],[\"POS\",-0.5013656364891583],[\"POS\",-0.501252354593772],[\"Relations\",-0.2810097744404242],[\"Relations\",-0.4473966156048882],[\"Relations\",-0.5084577691357417],[\"Relations\",-0.3380325112562319],[\"Relations\",-0.4541647411047742],[\"Relations\",-0.3893148814828261],[\"Relations\",-0.421047074206068],[\"Relations\",-0.45479191418941034],[\"Relations\",-0.4491157410790485],[\"Relations\",-0.4759186083501203],[\"Relations\",-0.44879212371195404],[\"Relations\",-0.42085915537429197],[\"Relations\",-0.4965869965709158],[\"Relations\",-0.4695859343912038],[\"Relations\",-0.43088872254097815],[\"Relations\",-0.40812695338126204],[\"Relations\",-0.4279434396207782],[\"Relations\",-0.4873620100926022],[\"Relations\",-0.4520400433127205],[\"Relations\",-0.4532621276226876],[\"Relations\",-0.4908838382117171],[\"Relations\",-0.44742173276179603],[\"Relations\",-0.5291015616010672],[\"Relations\",-0.4678961458829124],[\"SPR\",-0.4021549339653747],[\"SPR\",-0.42428927439112135],[\"SPR\",-0.4427049771501718],[\"SPR\",-0.366651411837394],[\"SPR\",-0.4598083461104998],[\"SPR\",-0.44032748280457656],[\"SPR\",-0.4570408511567553],[\"SPR\",-0.43905652137373347],[\"SPR\",-0.4205045115629539],[\"SPR\",-0.4259943392631838],[\"SPR\",-0.47195554585164196],[\"SPR\",-0.38240876464951784],[\"SPR\",-0.5061247685112321],[\"SPR\",-0.4416989537999864],[\"SPR\",-0.4518793063115939],[\"SPR\",-0.37680814750125236],[\"SPR\",-0.4575109014039892],[\"SPR\",-0.44774504449761543],[\"SPR\",-0.4825359765148968],[\"SPR\",-0.458231612667788],[\"SPR\",-0.4302766672319035],[\"SPR\",-0.49599513596737715],[\"SPR\",-0.4682965955490598],[\"SPR\",-0.5436214386873615],[\"SRL\",-0.4402286837439977],[\"SRL\",-0.07547103804723737],[\"SRL\",-0.7288950954687352],[\"SRL\",-0.12475370708006245],[\"SRL\",-0.479107911966435],[\"SRL\",-0.49002486309517623],[\"SRL\",-0.3917327298022487],[\"SRL\",-0.3460593810431991],[\"SRL\",-0.5581802448666476],[\"SRL\",-0.39147271907243153],[\"SRL\",-0.34470216310226187],[\"SRL\",-0.48101564365984606],[\"SRL\",-0.39576240087569664],[\"SRL\",-0.4463523946894639],[\"SRL\",-0.5047203356488055],[\"SRL\",-0.4598927848536645],[\"SRL\",-0.5190481169197733],[\"SRL\",-0.5280051592984751],[\"SRL\",-0.47358075616478074],[\"SRL\",-0.4709927682280303],[\"SRL\",-0.5000697709101073],[\"SRL\",-0.5277366245838504],[\"SRL\",-0.4764170889764226],[\"SRL\",-0.525178457570553]],\"_bar_height\":{\"__ndarray__\":\"7T+UGTCb1D/mYSgCFqC7PyRHSzTmsac/chOrGr9C0z+jkxlyqv+0P3k2DD77loE/eDnTZpTktj9XEGVK76bGP3k7EdkYBbM/dZXZFRdKxD9HY3ieajzPP/iFnVqx9qE/e16AEhMYzz+W48c2IePDP62ti4YiRdA/k/QG/SNKuj+4OyZN6APDP2uJdtFB68E/K6Datm5eZD/JVG4ghFisPzsCwY5DvKg/R7cDKCVboD/RU+OpqQVvP3loCTfz7KE/JTWeBL4O5j863OttqZ/NPwMbiGyRY8g//0EzTEXA3j/GmnasbuqzPzvyL3wPP5c/OCxgdO/Ltz/CK1S3coGkP4HUXJSswas/6y+gQ/YcyD9aYhEgTErOP1C6l9kxbMU/iVrvgatetz+uVgD0GYW6P72vgnoFSYo/Pwhc8DcisT/qzfTkdoiUP64X2MYlnWQ/ZFbdIYAhqD+Pn60Hg+mDP6GJBdBff4E/FO7evulvlz9r8dwXHq2LP997j0/Lw3c/AAAAAAAA8D+p+Bxs0FibPyJxiSqej7c/KAp6pTv9yT9oemkZJ6DRP9CZGHFOL48/3+T4PSUPuz//PQNU6GKnPxnf4Rttfag/nacG//7Drz9ZgcUWaJnKP9hbDcLMf5c/JC32qVPqtj8ypkBJLAyuPwvwBRbhRbk/+Wk4iLKruD/EuEzGXLSgP4aIq9jahKs/Z1Emef21lT8RI5kVTPGJP+wiAp5SQKg/8rwVjeltqD8mh/8f3Qt+P1iHDDhHtrE/AAAAAAAA8D/WSIehWuPLP5lrkT5jnbc/8JcGBJQG4T++YRP7yTW8P4JdKzZGqIs/pXn+H4x6pj96GX3ZYjGyP1wzbONXlLI/pYAqWA2Xwz80O61vbe3BP9FQDhuRe7w/DzrkZUO2lj8sHCdiWnCRPyzrNzq+Q5U/0hIuJT4EsD/QUEjtFCC5Pyi7sERqyLw/Yu3NoZFWlz8cyhXA5dOSPznyWiyxlLM/jqKi5eUPoj/KzB0UZiekPyzOruNgj5M/AAAAAAAA8D9sAm19mJjfPxEffGloB8c/PJWifWvo1D/uF/nDnITAP1Qqxl46rLE/nlLf7hUMuT/2cXhVzEyrP1J8s4yzqZY/HC8nCgVerz/U7ruASUi6P1PTbroko7M/AiyR1uzhsD+MQpI0UNCAP0IUNPt5HqM/1HLJE5m1nz+yzoS9ciuePxKglv6Slnw/1hXIUz3Okz9iDGbcOfGRP5sPWBhHqTc/426Hm9G5bz+pQ8kD5V9mPzTefIHBhGQ/cwV2KN8H3D+Nl0Wv1O66P+VXro5OUpE/ybmVxVm71D8m2eoTuHe3P7dlLyTcVcw/J101SkI2xD8ceiSkgyW3P6Cz5GeADbo/UUhQ1sqoqD/J1+gz6ze6P9D6cQuTQsQ/flt9Q5b1ez8fQYNk3SSvP9yleNRGscE/SoKc8v2Exz9wf0p6THLCP2kyt0ry4Zk/IZj6GjWOuD9Cu7DCBu63P/A794V+q5I/O3CJ5Inruj+BQFu9zMytPw9TBJfqb7A/wZSxzl8MyT/7UXIyx2HDP8gnuvLFVb0/MCaQCJER0T+hGw4eAJS0PxEQpmtljb4/0wOx1r3+tT92ZTXP+zO/P8dDBPvQWcQ/DWCV9Ajywj+LAJt1r7esPzxmII51Gs4/R5M4B0kWiT9m14B9otm9P2wZTotGo7g/j6OdUYCJzz/PEdCRIcG1Px6U31kpwbo/EX/mxhbioT8UcDKDqmK1P0rRAWpj2cE/2324gGdngD/MyZO6bTuwP8gkIpmMVbY/AecdkViavj81r/KFeyvrP9FioDpvTN0/21MCBwkE6D/CsmVLvGSlPw8XPDbYbZQ/Wf65YGe3yz/BBPmBU7TTP8t38xHNyb0/KsZOonHIyz8Mw06tzODTP4Fed5aicKM//Z9At1Cvyj87i6Lssne7PyTgzXOhVYM/GjjG0u6ItD8pHOJ8WYGjPwGSOW1iraw/6n0HcaUNqz8UfztfErStP60Yxhs/SiI/9830Xf1mrD+061xeHiaoP54mUa9hyKk/\",\"dtype\":\"float64\",\"shape\":[192]},\"_display_name\":[\"Coref.\",\"Coref.\",\"Coref.\",\"Coref.\",\"Coref.\",\"Coref.\",\"Coref.\",\"Coref.\",\"Coref.\",\"Coref.\",\"Coref.\",\"Coref.\",\"Coref.\",\"Coref.\",\"Coref.\",\"Coref.\",\"Coref.\",\"Coref.\",\"Coref.\",\"Coref.\",\"Coref.\",\"Coref.\",\"Coref.\",\"Coref.\",\"Deps.\",\"Deps.\",\"Deps.\",\"Deps.\",\"Deps.\",\"Deps.\",\"Deps.\",\"Deps.\",\"Deps.\",\"Deps.\",\"Deps.\",\"Deps.\",\"Deps.\",\"Deps.\",\"Deps.\",\"Deps.\",\"Deps.\",\"Deps.\",\"Deps.\",\"Deps.\",\"Deps.\",\"Deps.\",\"Deps.\",\"Deps.\",\"Entities\",\"Entities\",\"Entities\",\"Entities\",\"Entities\",\"Entities\",\"Entities\",\"Entities\",\"Entities\",\"Entities\",\"Entities\",\"Entities\",\"Entities\",\"Entities\",\"Entities\",\"Entities\",\"Entities\",\"Entities\",\"Entities\",\"Entities\",\"Entities\",\"Entities\",\"Entities\",\"Entities\",\"Consts.\",\"Consts.\",\"Consts.\",\"Consts.\",\"Consts.\",\"Consts.\",\"Consts.\",\"Consts.\",\"Consts.\",\"Consts.\",\"Consts.\",\"Consts.\",\"Consts.\",\"Consts.\",\"Consts.\",\"Consts.\",\"Consts.\",\"Consts.\",\"Consts.\",\"Consts.\",\"Consts.\",\"Consts.\",\"Consts.\",\"Consts.\",\"POS\",\"POS\",\"POS\",\"POS\",\"POS\",\"POS\",\"POS\",\"POS\",\"POS\",\"POS\",\"POS\",\"POS\",\"POS\",\"POS\",\"POS\",\"POS\",\"POS\",\"POS\",\"POS\",\"POS\",\"POS\",\"POS\",\"POS\",\"POS\",\"Relations\",\"Relations\",\"Relations\",\"Relations\",\"Relations\",\"Relations\",\"Relations\",\"Relations\",\"Relations\",\"Relations\",\"Relations\",\"Relations\",\"Relations\",\"Relations\",\"Relations\",\"Relations\",\"Relations\",\"Relations\",\"Relations\",\"Relations\",\"Relations\",\"Relations\",\"Relations\",\"Relations\",\"SPR\",\"SPR\",\"SPR\",\"SPR\",\"SPR\",\"SPR\",\"SPR\",\"SPR\",\"SPR\",\"SPR\",\"SPR\",\"SPR\",\"SPR\",\"SPR\",\"SPR\",\"SPR\",\"SPR\",\"SPR\",\"SPR\",\"SPR\",\"SPR\",\"SPR\",\"SPR\",\"SPR\",\"SRL\",\"SRL\",\"SRL\",\"SRL\",\"SRL\",\"SRL\",\"SRL\",\"SRL\",\"SRL\",\"SRL\",\"SRL\",\"SRL\",\"SRL\",\"SRL\",\"SRL\",\"SRL\",\"SRL\",\"SRL\",\"SRL\",\"SRL\",\"SRL\",\"SRL\",\"SRL\",\"SRL\"],\"_fill_color\":[\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#fd8d3c\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#fd8d3c\",\"#756bb1\",\"#756bb1\",\"#fd8d3c\",\"#fd8d3c\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#fd8d3c\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#fd8d3c\",\"#756bb1\",\"#fd8d3c\",\"#fd8d3c\",\"#756bb1\",\"#fd8d3c\",\"#756bb1\",\"#fd8d3c\",\"#fd8d3c\",\"#756bb1\",\"#756bb1\",\"#fd8d3c\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#fd8d3c\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#fd8d3c\",\"#756bb1\",\"#756bb1\",\"#fd8d3c\",\"#fd8d3c\",\"#756bb1\",\"#fd8d3c\",\"#fd8d3c\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#fd8d3c\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#fd8d3c\",\"#fd8d3c\",\"#756bb1\",\"#756bb1\",\"#fd8d3c\",\"#756bb1\",\"#fd8d3c\",\"#756bb1\",\"#fd8d3c\",\"#fd8d3c\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#fd8d3c\",\"#fd8d3c\",\"#756bb1\",\"#fd8d3c\",\"#756bb1\",\"#756bb1\",\"#fd8d3c\",\"#fd8d3c\",\"#fd8d3c\",\"#fd8d3c\",\"#fd8d3c\",\"#756bb1\",\"#756bb1\",\"#fd8d3c\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#fd8d3c\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#fd8d3c\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#fd8d3c\",\"#756bb1\",\"#756bb1\",\"#fd8d3c\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#fd8d3c\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#fd8d3c\",\"#756bb1\",\"#fd8d3c\",\"#fd8d3c\",\"#756bb1\",\"#756bb1\",\"#fd8d3c\",\"#fd8d3c\",\"#756bb1\",\"#fd8d3c\"],\"_formatted_exp_layer\":[\"9.47\",\"9.47\",\"9.47\",\"9.47\",\"9.47\",\"9.47\",\"9.47\",\"9.47\",\"9.47\",\"9.47\",\"9.47\",\"9.47\",\"9.47\",\"9.47\",\"9.47\",\"9.47\",\"9.47\",\"9.47\",\"9.47\",\"9.47\",\"9.47\",\"9.47\",\"9.47\",\"9.47\",\"5.69\",\"5.69\",\"5.69\",\"5.69\",\"5.69\",\"5.69\",\"5.69\",\"5.69\",\"5.69\",\"5.69\",\"5.69\",\"5.69\",\"5.69\",\"5.69\",\"5.69\",\"5.69\",\"5.69\",\"5.69\",\"5.69\",\"5.69\",\"5.69\",\"5.69\",\"5.69\",\"5.69\",\"4.64\",\"4.64\",\"4.64\",\"4.64\",\"4.64\",\"4.64\",\"4.64\",\"4.64\",\"4.64\",\"4.64\",\"4.64\",\"4.64\",\"4.64\",\"4.64\",\"4.64\",\"4.64\",\"4.64\",\"4.64\",\"4.64\",\"4.64\",\"4.64\",\"4.64\",\"4.64\",\"4.64\",\"3.79\",\"3.79\",\"3.79\",\"3.79\",\"3.79\",\"3.79\",\"3.79\",\"3.79\",\"3.79\",\"3.79\",\"3.79\",\"3.79\",\"3.79\",\"3.79\",\"3.79\",\"3.79\",\"3.79\",\"3.79\",\"3.79\",\"3.79\",\"3.79\",\"3.79\",\"3.79\",\"3.79\",\"3.39\",\"3.39\",\"3.39\",\"3.39\",\"3.39\",\"3.39\",\"3.39\",\"3.39\",\"3.39\",\"3.39\",\"3.39\",\"3.39\",\"3.39\",\"3.39\",\"3.39\",\"3.39\",\"3.39\",\"3.39\",\"3.39\",\"3.39\",\"3.39\",\"3.39\",\"3.39\",\"3.39\",\"9.40\",\"9.40\",\"9.40\",\"9.40\",\"9.40\",\"9.40\",\"9.40\",\"9.40\",\"9.40\",\"9.40\",\"9.40\",\"9.40\",\"9.40\",\"9.40\",\"9.40\",\"9.40\",\"9.40\",\"9.40\",\"9.40\",\"9.40\",\"9.40\",\"9.40\",\"9.40\",\"9.40\",\"9.93\",\"9.93\",\"9.93\",\"9.93\",\"9.93\",\"9.93\",\"9.93\",\"9.93\",\"9.93\",\"9.93\",\"9.93\",\"9.93\",\"9.93\",\"9.93\",\"9.93\",\"9.93\",\"9.93\",\"9.93\",\"9.93\",\"9.93\",\"9.93\",\"9.93\",\"9.93\",\"9.93\",\"6.54\",\"6.54\",\"6.54\",\"6.54\",\"6.54\",\"6.54\",\"6.54\",\"6.54\",\"6.54\",\"6.54\",\"6.54\",\"6.54\",\"6.54\",\"6.54\",\"6.54\",\"6.54\",\"6.54\",\"6.54\",\"6.54\",\"6.54\",\"6.54\",\"6.54\",\"6.54\",\"6.54\"],\"_formatted_kl_unif\":[\"K(\\u0394) = 0.60\",\"K(\\u0394) = 0.60\",\"K(\\u0394) = 0.60\",\"K(\\u0394) = 0.60\",\"K(\\u0394) = 0.60\",\"K(\\u0394) = 0.60\",\"K(\\u0394) = 0.60\",\"K(\\u0394) = 0.60\",\"K(\\u0394) = 0.60\",\"K(\\u0394) = 0.60\",\"K(\\u0394) = 0.60\",\"K(\\u0394) = 0.60\",\"K(\\u0394) = 0.60\",\"K(\\u0394) = 0.60\",\"K(\\u0394) = 0.60\",\"K(\\u0394) = 0.60\",\"K(\\u0394) = 0.60\",\"K(\\u0394) = 0.60\",\"K(\\u0394) = 0.60\",\"K(\\u0394) = 0.60\",\"K(\\u0394) = 0.60\",\"K(\\u0394) = 0.60\",\"K(\\u0394) = 0.60\",\"K(\\u0394) = 0.60\",\"K(\\u0394) = 1.15\",\"K(\\u0394) = 1.15\",\"K(\\u0394) = 1.15\",\"K(\\u0394) = 1.15\",\"K(\\u0394) = 1.15\",\"K(\\u0394) = 1.15\",\"K(\\u0394) = 1.15\",\"K(\\u0394) = 1.15\",\"K(\\u0394) = 1.15\",\"K(\\u0394) = 1.15\",\"K(\\u0394) = 1.15\",\"K(\\u0394) = 1.15\",\"K(\\u0394) = 1.15\",\"K(\\u0394) = 1.15\",\"K(\\u0394) = 1.15\",\"K(\\u0394) = 1.15\",\"K(\\u0394) = 1.15\",\"K(\\u0394) = 1.15\",\"K(\\u0394) = 1.15\",\"K(\\u0394) = 1.15\",\"K(\\u0394) = 1.15\",\"K(\\u0394) = 1.15\",\"K(\\u0394) = 1.15\",\"K(\\u0394) = 1.15\",\"K(\\u0394) = 1.61\",\"K(\\u0394) = 1.61\",\"K(\\u0394) = 1.61\",\"K(\\u0394) = 1.61\",\"K(\\u0394) = 1.61\",\"K(\\u0394) = 1.61\",\"K(\\u0394) = 1.61\",\"K(\\u0394) = 1.61\",\"K(\\u0394) = 1.61\",\"K(\\u0394) = 1.61\",\"K(\\u0394) = 1.61\",\"K(\\u0394) = 1.61\",\"K(\\u0394) = 1.61\",\"K(\\u0394) = 1.61\",\"K(\\u0394) = 1.61\",\"K(\\u0394) = 1.61\",\"K(\\u0394) = 1.61\",\"K(\\u0394) = 1.61\",\"K(\\u0394) = 1.61\",\"K(\\u0394) = 1.61\",\"K(\\u0394) = 1.61\",\"K(\\u0394) = 1.61\",\"K(\\u0394) = 1.61\",\"K(\\u0394) = 1.61\",\"K(\\u0394) = 1.57\",\"K(\\u0394) = 1.57\",\"K(\\u0394) = 1.57\",\"K(\\u0394) = 1.57\",\"K(\\u0394) = 1.57\",\"K(\\u0394) = 1.57\",\"K(\\u0394) = 1.57\",\"K(\\u0394) = 1.57\",\"K(\\u0394) = 1.57\",\"K(\\u0394) = 1.57\",\"K(\\u0394) = 1.57\",\"K(\\u0394) = 1.57\",\"K(\\u0394) = 1.57\",\"K(\\u0394) = 1.57\",\"K(\\u0394) = 1.57\",\"K(\\u0394) = 1.57\",\"K(\\u0394) = 1.57\",\"K(\\u0394) = 1.57\",\"K(\\u0394) = 1.57\",\"K(\\u0394) = 1.57\",\"K(\\u0394) = 1.57\",\"K(\\u0394) = 1.57\",\"K(\\u0394) = 1.57\",\"K(\\u0394) = 1.57\",\"K(\\u0394) = 1.60\",\"K(\\u0394) = 1.60\",\"K(\\u0394) = 1.60\",\"K(\\u0394) = 1.60\",\"K(\\u0394) = 1.60\",\"K(\\u0394) = 1.60\",\"K(\\u0394) = 1.60\",\"K(\\u0394) = 1.60\",\"K(\\u0394) = 1.60\",\"K(\\u0394) = 1.60\",\"K(\\u0394) = 1.60\",\"K(\\u0394) = 1.60\",\"K(\\u0394) = 1.60\",\"K(\\u0394) = 1.60\",\"K(\\u0394) = 1.60\",\"K(\\u0394) = 1.60\",\"K(\\u0394) = 1.60\",\"K(\\u0394) = 1.60\",\"K(\\u0394) = 1.60\",\"K(\\u0394) = 1.60\",\"K(\\u0394) = 1.60\",\"K(\\u0394) = 1.60\",\"K(\\u0394) = 1.60\",\"K(\\u0394) = 1.60\",\"K(\\u0394) = 0.50\",\"K(\\u0394) = 0.50\",\"K(\\u0394) = 0.50\",\"K(\\u0394) = 0.50\",\"K(\\u0394) = 0.50\",\"K(\\u0394) = 0.50\",\"K(\\u0394) = 0.50\",\"K(\\u0394) = 0.50\",\"K(\\u0394) = 0.50\",\"K(\\u0394) = 0.50\",\"K(\\u0394) = 0.50\",\"K(\\u0394) = 0.50\",\"K(\\u0394) = 0.50\",\"K(\\u0394) = 0.50\",\"K(\\u0394) = 0.50\",\"K(\\u0394) = 0.50\",\"K(\\u0394) = 0.50\",\"K(\\u0394) = 0.50\",\"K(\\u0394) = 0.50\",\"K(\\u0394) = 0.50\",\"K(\\u0394) = 0.50\",\"K(\\u0394) = 0.50\",\"K(\\u0394) = 0.50\",\"K(\\u0394) = 0.50\",\"K(\\u0394) = 0.33\",\"K(\\u0394) = 0.33\",\"K(\\u0394) = 0.33\",\"K(\\u0394) = 0.33\",\"K(\\u0394) = 0.33\",\"K(\\u0394) = 0.33\",\"K(\\u0394) = 0.33\",\"K(\\u0394) = 0.33\",\"K(\\u0394) = 0.33\",\"K(\\u0394) = 0.33\",\"K(\\u0394) = 0.33\",\"K(\\u0394) = 0.33\",\"K(\\u0394) = 0.33\",\"K(\\u0394) = 0.33\",\"K(\\u0394) = 0.33\",\"K(\\u0394) = 0.33\",\"K(\\u0394) = 0.33\",\"K(\\u0394) = 0.33\",\"K(\\u0394) = 0.33\",\"K(\\u0394) = 0.33\",\"K(\\u0394) = 0.33\",\"K(\\u0394) = 0.33\",\"K(\\u0394) = 0.33\",\"K(\\u0394) = 0.33\",\"K(\\u0394) = 1.31\",\"K(\\u0394) = 1.31\",\"K(\\u0394) = 1.31\",\"K(\\u0394) = 1.31\",\"K(\\u0394) = 1.31\",\"K(\\u0394) = 1.31\",\"K(\\u0394) = 1.31\",\"K(\\u0394) = 1.31\",\"K(\\u0394) = 1.31\",\"K(\\u0394) = 1.31\",\"K(\\u0394) = 1.31\",\"K(\\u0394) = 1.31\",\"K(\\u0394) = 1.31\",\"K(\\u0394) = 1.31\",\"K(\\u0394) = 1.31\",\"K(\\u0394) = 1.31\",\"K(\\u0394) = 1.31\",\"K(\\u0394) = 1.31\",\"K(\\u0394) = 1.31\",\"K(\\u0394) = 1.31\",\"K(\\u0394) = 1.31\",\"K(\\u0394) = 1.31\",\"K(\\u0394) = 1.31\",\"K(\\u0394) = 1.31\"],\"_line_color\":[\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#e6550d\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#e6550d\",\"#756bb1\",\"#756bb1\",\"#e6550d\",\"#e6550d\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#e6550d\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#e6550d\",\"#756bb1\",\"#e6550d\",\"#e6550d\",\"#756bb1\",\"#e6550d\",\"#756bb1\",\"#e6550d\",\"#e6550d\",\"#756bb1\",\"#756bb1\",\"#e6550d\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#e6550d\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#e6550d\",\"#756bb1\",\"#756bb1\",\"#e6550d\",\"#e6550d\",\"#756bb1\",\"#e6550d\",\"#e6550d\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#e6550d\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#e6550d\",\"#e6550d\",\"#756bb1\",\"#756bb1\",\"#e6550d\",\"#756bb1\",\"#e6550d\",\"#756bb1\",\"#e6550d\",\"#e6550d\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#e6550d\",\"#e6550d\",\"#756bb1\",\"#e6550d\",\"#756bb1\",\"#756bb1\",\"#e6550d\",\"#e6550d\",\"#e6550d\",\"#e6550d\",\"#e6550d\",\"#756bb1\",\"#756bb1\",\"#e6550d\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#e6550d\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#e6550d\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#e6550d\",\"#756bb1\",\"#756bb1\",\"#e6550d\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#e6550d\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#e6550d\",\"#756bb1\",\"#e6550d\",\"#e6550d\",\"#756bb1\",\"#756bb1\",\"#e6550d\",\"#e6550d\",\"#756bb1\",\"#e6550d\"],\"accuracy\":{\"__ndarray__\":\"oB9HXNx57T+V+aNBIJLtP4HL97tNlO0/W7M7X+y+7T99SyeuvsrtP9+eMj39y+0/UI2YRDDX7T8LPyf35e3tPxmpZsDl++0/cgfq41wR7j+ypG90IzXuP9ZtdnLqPO4/ZGF2uxFg7j+8jt4vlHnuP/n6SBFmoe4/8jbcVJOx7j/oEDk618nuPxpEfwGe3+4/kMU2Fq/e7j+7UqrQSNbuP5DFNhav3u4/tr9Yw2ri7j+2v1jDauLuP33IpT/R3O4/BRbEoPPa7z/6bmVhc93vP530V0CS3+8/T3iE+vXk7z9QkJJ61+XvP0YrCgSd5e8/8Kzv9K7m7z/J92I2IufvPxAtED3E5+8/FK6zIe3p7z9N63oEqezvP4OGMx6Z7u8/3YXxEbDv7z/Pdf1t6PDvP4cH1wLC8O8/UCpIIIzx7z+WR+emTPHvP6tKcfhF8e8/pof3Stfx7z9JFkeOt/HvP/YJH0jS8e8/FquqdIrx7z+TveZdYvHvPxk1q7108e8//9kVfVDH7z/bHOqb3sbvP1q3IuZvyO8/gbs9NA/M7z8Q5V1N+dDvP/pvKs6y0O8/l6OSSKDS7z/aAi3Gc9PvPySGw/Rc1O8/fFFShXHV7z+rgqjwK9nvP88/1NGd2e8/VPXJYD/b7z+mpZusQ9zvPzeaSjEL3u8/xoW6Sc3f7z+XkhTfOt/vP+UnKeYu4O8/BMqXgpDg7z/zbyFIWuDvP64HSF6B3+8/9HhgtF/g7z/qQuYqP+DvP4Y4nqQE3+8/aymEJd6V7z95TaCcLJvvP0DlVXkhne8/SIPXsKyp7z8LLfqCSazvP8T1SZfQrO8/KS3hO3Cr7z99MPSUCa3vP2oX5k+Tru8/oB7qcV+y7z+wumaI+rXvP3WiJWtquO8/cZhHM3a47z+dvaNwILjvP4qISv4Nue8/Yhe9PEK67z/INQwPk7fvP2ft3JtXuu8/DkxAPuG57z87OttHX7rvP/n2wxzZuO8/iRUb7k+37z/UqoqZkbjvP95yFYVYue8/OeW8qszj7z+H31nS6ejvP9XRQZ7D6u8/0TbAYR/u7z9SNRgSeO/vPz0d/l4x8O8/qEqEfTTx7z/cD6xAwvHvP8nJowH98e8/QIN70aHy7z/2pMNbtfPvPxGkldiC9O8/2lFBczH17z9mIzP2HPXvP+qAyby69O8/kAAt8Av17z8uGCeyvPTvP43prPrP9O8/DlK/DAP17z+HaV/z1PTvP3EM177T9O8/fAxyzcn07z8omNmqwfTvP6Vpp2+69O8/NyeQrdkb7z92cyhGVifvP/2lI+D6Iu8/MWteEhIu7z8Zfwp4YzbvPxahcap/P+8/0ZindjtG7z8/3052MUrvP6OemA/CTe8/Bl7iqFJR7z+rR12oQ1fvP5JbCQ6VX+8/yf7cDZBh7z/2GlOnJWPvP90u/wx3a+8/5dfDpfh07z/CZBKl5HzvP9hyzXGvfe8/UUDS1wqC7z/gG5IKMYfvP+ui73CWh+8/ppolPVKO7z9Z6ZZwjIvvP8cvPnCCj+8/E01GLxS46z+K/vDCjNTrP6+VpD153es/AbCbVgXx6z8jUYc/GPnrP1yxBlyxBuw/yns9Awoh7D/qIUUjsCjsPzw8PDw8POw/cqbzxvtI7D8+NyAFqTzsP+BwKm5UY+w/7khKtbpm7D80hgVQTXfsP1sYnZOmgOw/rTKUrDKU7D/7VsMz5absPzetCuJXtew/PZ62PJ627D90A1KQysPsP429yYy9yew/n4uxZf3N7D/LDvUDndjsP2kh+to9wew/Fbnqm7Se7z85cFZ6Eq/vP7a+sf5npu8/1XgbuvG07z/98ywhqLXvPxhUMtoUtu8/MFaoHzm67z+BeOZiTcDvPw4xn4oDvu8/k5D0M2vC7z9NI6yJkMjvP0VVw7iPye8/mbs/5LTN7z/9vY2x28/vP067Z1yyz+8/TLSwf0jR7z+R0wWIfNDvP5e0iAdLz+8/trHSV3XQ7z9QjnwirdHvP8+XyfmT0e8/5L1FhIXQ7z9taJDyZ9HvPwOFv6Vy0O8/\",\"dtype\":\"float64\",\"shape\":[192]},\"accuracy_errn95\":{\"__ndarray__\":\"I3yTc4araj9GNvu62zRqP5fzypgQKmo/bPM16ctRaT90KthEChRpPwj7VyN+DWk/QL5mZyjSaD99ccfhg1doP7LJawJMCmg/gQiXnV+RZz+9185WlMBmP5KakjLpkWY/9lwDCsq4ZT8hj09JZRRlP4+RKu3VBmQ/X1IbFVOUYz9lCw91geJiP9kPmsYiPGI/nnVgRGhDYj9IiLD2RIRiP551YERoQ2I/3gTIET4mYj/eBMgRPiZiP60QSDrpUWI/qKPaIX3EHj/anRV1XrcdP1TIuD8qyxw/UbN8PwpNGj8Dq4080d4ZP+J03j6S+xk/eXAQjLpzGT9dFtbmtTkZP5zm2bY+5xg/BuW7NVXFFz/IQBU2/EAWP2r+AuOqHBU/mFLKixFxFD9KhD2A7KkTPxLhnPnXwhM/IH3iEFI+Ez817yarUmgTP27+SzO5bBM/3m5JFRwMEz9udRCCXyETP3YcySh5DxM/ar88Nm4/Ez/iW7h6/lkTPx8aiELWTRM/2G1g/l0fMT//0s+caTAxPwfk664K9DA/ljiOWx9lMD8VDlkMrDUvP6UTtEjlTC8/xX67mdqoLj9H7MaCd2EuP01emz35ES4/IhyRApeyLT/G9FyQml8sP8cUTZ0SNiw/qWYdJqqbKz99rZu8pTkrP1U1456niio/DcA+ix/ZKT8e6UasZhMqP3yadNn6sSk/jnLvN5mKKT/ddnG2gaApP/V+VPpn9yk/XYYvuFGeKT9tjrzWbqspPxAG6czaKCo/32/GaV4AFT9k8WlG9XkUPyO0BCp6RxQ/j9Cxj732Ej/WXyrVe60SP4UnHrqLnhI/1gVT/mjFEj+WiXePOpgSP8N773dYbBI/WXIV5yH+ET/ClAeh4ZIRP3syeqLdSBE/ycFXpnRHET/TjPSQtVERP6bwrB0/NRE/HqinEgcQET/CrS06j2IRP52zJ1hvDRE/yOLJRMYbET+s+7n7gAwRPzROgFeZOxE/W0U+d4lqET+vnE+wLEQRP/Mo7RlHLBE/BQyTM7ohAD+EsuT9ejP9PnmKerZkAvw+uX3D5Fu0+T7hAXW5Orj4Ptm5XGdoLPg+tJEuWl5j9z4dZuLVcvL2PlleWa0Aw/Y+uMGgJMk79j5Ekcd5MlL1PmwuZhk6nfQ+UyEIdGb+8z51AtkDSxH0PizGRP3pavQ+9bW1EfAg9D5B4DNnJGn0PkHXqgmqV/Q+0pGEWhYp9D6IvUIKJlP0Po3H4l8+VPQ+zhX130Rd9D6XWf1LpGT0PsbfEsIva/Q+Eo4msfVeYj+XV78nWOphP8U3n9z2FmI/4DVYLGukYT//3PD4V0xhP7ebjima6WA/AEuCjv6eYD822Le8bXJgPx5QYYffSWA/p6G4weEgYD//PDQLHrdfP0tXMGSS8F4/OZNMfn/AXj/KVOMaz5leP4Z5jLY1y10/FVIQiHbXXD9iv8R1jAVcP5Su3+Qx8Fs/dTL/Q4N5Wz/uQpi0cepaP+Z9uNBO31o/pd4Os/oeWj/C+Mr+325aP+UDb2Vt/Fk/GWL4AeGucz8v6A5B9nZzP53rrkUyZXM/9TScf989cz97xHD4di1zPwaTU0GbEXM/hSJ3U9Hacj+ZkULGtMpyP8oPkl4aoXI/SEk+06GFcj8JJiEQMaByP5YmA1P9S3I/BbZk+XZEcj9Y57F2fR9yP7mEYpZqCnI/grL+d9bdcT/s9wmCh7JxPwmHUqyakHE/+1coWpeNcT8S9Ey3RG5xP54REjMCYHE/ibXFbMdVcT+HVIn1CjxxP2BTVqFbdHE/z6JDcYM3Ij8f5q3xhKEgP9wSFEhIfSE/AEbxKqIFID+MhS1kmOQfPwLlhjt0zR8/RcH6dRnoHj8dHOrBaYodPxbeckH6Dx4/Ps1asK4MHT+dgqslgZIbP/GcLwsvUxs/h0QgK01FGj9R13gzvrQZP8DDgha0vxk/LVeOlS5TGT8S1nnN6YkZPya7kP0F2xk/DdakZtWLGT/7v5PGADgZP+cezgjPPhk/Q6/JGIOHGT+RDaB6s0oZP862VLaNjBk/\",\"dtype\":\"float64\",\"shape\":[192]},\"contextual_headroom\":[0.11639055893469108,0.11639055893469108,0.11639055893469108,0.11639055893469108,0.11639055893469108,0.11639055893469108,0.11639055893469108,0.11639055893469108,0.11639055893469108,0.11639055893469108,0.11639055893469108,0.11639055893469108,0.11639055893469108,0.11639055893469108,0.11639055893469108,0.11639055893469108,0.11639055893469108,0.11639055893469108,0.11639055893469108,0.11639055893469108,0.11639055893469108,0.11639055893469108,0.11639055893469108,0.11639055893469108,0.09997559540642187,0.09997559540642187,0.09997559540642187,0.09997559540642187,0.09997559540642187,0.09997559540642187,0.09997559540642187,0.09997559540642187,0.09997559540642187,0.09997559540642187,0.09997559540642187,0.09997559540642187,0.09997559540642187,0.09997559540642187,0.09997559540642187,0.09997559540642187,0.09997559540642187,0.09997559540642187,0.09997559540642187,0.09997559540642187,0.09997559540642187,0.09997559540642187,0.09997559540642187,0.09997559540642187,0.05733773727377656,0.05733773727377656,0.05733773727377656,0.05733773727377656,0.05733773727377656,0.05733773727377656,0.05733773727377656,0.05733773727377656,0.05733773727377656,0.05733773727377656,0.05733773727377656,0.05733773727377656,0.05733773727377656,0.05733773727377656,0.05733773727377656,0.05733773727377656,0.05733773727377656,0.05733773727377656,0.05733773727377656,0.05733773727377656,0.05733773727377656,0.05733773727377656,0.05733773727377656,0.05733773727377656,0.1369172609382292,0.1369172609382292,0.1369172609382292,0.1369172609382292,0.1369172609382292,0.1369172609382292,0.1369172609382292,0.1369172609382292,0.1369172609382292,0.1369172609382292,0.1369172609382292,0.1369172609382292,0.1369172609382292,0.1369172609382292,0.1369172609382292,0.1369172609382292,0.1369172609382292,0.1369172609382292,0.1369172609382292,0.1369172609382292,0.1369172609382292,0.1369172609382292,0.1369172609382292,0.1369172609382292,0.08318042260149905,0.08318042260149905,0.08318042260149905,0.08318042260149905,0.08318042260149905,0.08318042260149905,0.08318042260149905,0.08318042260149905,0.08318042260149905,0.08318042260149905,0.08318042260149905,0.08318042260149905,0.08318042260149905,0.08318042260149905,0.08318042260149905,0.08318042260149905,0.08318042260149905,0.08318042260149905,0.08318042260149905,0.08318042260149905,0.08318042260149905,0.08318042260149905,0.08318042260149905,0.08318042260149905,0.23439707290638978,0.23439707290638978,0.23439707290638978,0.23439707290638978,0.23439707290638978,0.23439707290638978,0.23439707290638978,0.23439707290638978,0.23439707290638978,0.23439707290638978,0.23439707290638978,0.23439707290638978,0.23439707290638978,0.23439707290638978,0.23439707290638978,0.23439707290638978,0.23439707290638978,0.23439707290638978,0.23439707290638978,0.23439707290638978,0.23439707290638978,0.23439707290638978,0.23439707290638978,0.23439707290638978,0.06260312292920267,0.06260312292920267,0.06260312292920267,0.06260312292920267,0.06260312292920267,0.06260312292920267,0.06260312292920267,0.06260312292920267,0.06260312292920267,0.06260312292920267,0.06260312292920267,0.06260312292920267,0.06260312292920267,0.06260312292920267,0.06260312292920267,0.06260312292920267,0.06260312292920267,0.06260312292920267,0.06260312292920267,0.06260312292920267,0.06260312292920267,0.06260312292920267,0.06260312292920267,0.06260312292920267,0.10353468382410691,0.10353468382410691,0.10353468382410691,0.10353468382410691,0.10353468382410691,0.10353468382410691,0.10353468382410691,0.10353468382410691,0.10353468382410691,0.10353468382410691,0.10353468382410691,0.10353468382410691,0.10353468382410691,0.10353468382410691,0.10353468382410691,0.10353468382410691,0.10353468382410691,0.10353468382410691,0.10353468382410691,0.10353468382410691,0.10353468382410691,0.10353468382410691,0.10353468382410691,0.10353468382410691],\"delta_score\":[0.013879441257917402,0.004651805956420341,0.0019949832561770853,0.012973188412789494,0.003535951670998738,-0.0003702407581366307,0.003854913478508748,0.007628730540243489,0.0032027459523230606,0.006833033344139872,0.010519605663694698,0.0015124410673706956,0.010471796336309458,0.006697584774402521,0.010958802965727377,0.004426884538286768,0.006403926892257106,0.006034720166532503,0.00010718428834255445,-0.0023865592874846575,0.0020825865972845525,0.0013770892203930352,-0.00016324335843065363,-0.0015092368295099856,0.02552338412121402,0.008569574507726108,0.007055262072416357,0.017791407828561145,0.0028806265752692184,-0.0008405908876449875,0.003441958198510009,0.0014829754309192422,0.00200736152590697,0.006975476846320716,0.008762393481853148,0.0061971665344429105,0.003380222973357938,0.003835858678077675,-0.0004752391681167589,0.0024782240535842215,-0.0007424787750688333,-9.31750350343652e-05,0.001745151356686736,-0.0003600133125067906,0.0003163571601318971,-0.0008474913440715826,-0.0005003885662981933,0.0002148349005205441,0.02747614170542223,-0.0005671336455403964,0.0019544774873441195,0.004311809685775048,0.005848448076223534,-0.00032336250990172566,0.0022446630826036262,0.0009699948096050237,0.0010157682989533345,0.0013175406411705115,0.004413022262864885,0.00048733796082711667,0.0019009168018350175,0.0012462807948429022,0.0020964911351403215,0.0020465302514487416,-0.0006928534156666055,0.0011414027393170656,0.00045025094750783534,-0.0002690046481890196,-0.0010058683529091672,0.0010132547474859255,-0.00015577883683715044,-0.0014692815263527281,0.05941261708359613,0.011048502584685815,0.004677767840125413,0.02698045911417002,0.005588037376253352,0.0006848171085261923,-0.0022263614877978677,0.0036037674074740345,0.003680337968767655,0.0077610405887247325,0.007102365457741455,0.005642029694835293,-0.0011247324085661425,-0.0008636008267759454,0.0010530576228330313,0.0031726639764402265,-0.004976981917454881,0.005701492956110887,-0.0011557425120003462,0.0009323786396909783,-0.0038786941524872054,-0.001788927583590283,0.0019961060253524954,0.0009686456541324606,0.03147784041096369,0.015209346190759088,0.005542698806958457,0.01006439317583152,0.003975623955219332,0.0021267767882398037,0.0030142324732994608,0.0016426685079516945,0.0006818248203487309,0.001887400396825334,0.003162874383283776,0.002363190365777923,0.002031677022008127,-0.00025292474215765637,-0.0011504127298819222,0.0009539925309216546,-0.0009076714488512883,0.00021502250903249198,0.0005958623098627491,-0.0005398029488270506,-1.1122820999132088e-05,-0.00011931107103668737,-8.414386688015973e-05,-7.716398841250971e-05,0.038022716937981205,0.009133392094210269,-0.0014685009842487773,0.02812200390187991,0.007958259645146293,0.019217976144238813,0.013708396076661522,0.007849365174594891,0.008834904702282875,0.004181190899440135,0.00889109356420037,0.013741023946374331,0.0005925911211828172,0.005280717002877577,0.011999615660160057,0.01595168385661072,0.012510997656734912,0.0021943021049737332,0.008327165529048552,0.008114978132677364,0.001582816029121914,0.009129031066018478,-0.005052830263922337,0.005574110691895617,0.0045373382940604445,0.0035109095276679714,0.002656923969406866,0.006183731894206845,0.0018637948512387759,0.0027671747625778176,0.0019921310192352326,0.002826112654943258,0.003686419136993635,0.0034318410937509425,0.0013004966003941076,0.005453021157068916,-0.00028402195260857077,0.0027035759719707952,0.002231485705491698,0.0057127368043372595,0.0019703335278200562,0.0024232025207228114,0.0008098536363528863,0.0019369122123800153,0.0032332580535665567,0.00018571629285113467,0.0014701719452714368,-0.0020228431766619037,0.004584003207641407,0.032558127296263395,-0.017554504694995754,0.028778523180469584,0.0016022635029485643,0.0007650167744763792,0.008303272287720986,0.011806069119540519,-0.004461980190427761,0.008323213123796913,0.011910157364277807,0.0014559550602089022,0.007994227309569446,0.004114361373145803,-0.0003620136732909174,0.0030759169179565005,-0.0014608450094321102,-0.002147781713638053,0.0020261541165566,0.0022246330149062743,-5.350895643019271e-06,-0.0021271871530643693,0.0018086290640578762,-0.0019309952916636286],\"display_col\":[\"bert-large-uncased-mix-01 (base)\",\"bert-large-uncased-mix-02 (base)\",\"bert-large-uncased-mix-03 (base)\",\"bert-large-uncased-mix-04 (base)\",\"bert-large-uncased-mix-05 (base)\",\"bert-large-uncased-mix-06 (base)\",\"bert-large-uncased-mix-07 (base)\",\"bert-large-uncased-mix-08 (base)\",\"bert-large-uncased-mix-09 (base)\",\"bert-large-uncased-mix-10 (base)\",\"bert-large-uncased-mix-11 (base)\",\"bert-large-uncased-mix-12 (base)\",\"bert-large-uncased-mix-13 (base)\",\"bert-large-uncased-mix-14 (base)\",\"bert-large-uncased-mix-15 (base)\",\"bert-large-uncased-mix-16 (base)\",\"bert-large-uncased-mix-17 (base)\",\"bert-large-uncased-mix-18 (base)\",\"bert-large-uncased-mix-19 (base)\",\"bert-large-uncased-mix-20 (base)\",\"bert-large-uncased-mix-21 (base)\",\"bert-large-uncased-mix-22 (base)\",\"bert-large-uncased-mix-23 (base)\",\"bert-large-uncased-mix-24 (base)\",\"bert-large-uncased-mix-01 (base)\",\"bert-large-uncased-mix-02 (base)\",\"bert-large-uncased-mix-03 (base)\",\"bert-large-uncased-mix-04 (base)\",\"bert-large-uncased-mix-05 (base)\",\"bert-large-uncased-mix-06 (base)\",\"bert-large-uncased-mix-07 (base)\",\"bert-large-uncased-mix-08 (base)\",\"bert-large-uncased-mix-09 (base)\",\"bert-large-uncased-mix-10 (base)\",\"bert-large-uncased-mix-11 (base)\",\"bert-large-uncased-mix-12 (base)\",\"bert-large-uncased-mix-13 (base)\",\"bert-large-uncased-mix-14 (base)\",\"bert-large-uncased-mix-15 (base)\",\"bert-large-uncased-mix-16 (base)\",\"bert-large-uncased-mix-17 (base)\",\"bert-large-uncased-mix-18 (base)\",\"bert-large-uncased-mix-19 (base)\",\"bert-large-uncased-mix-20 (base)\",\"bert-large-uncased-mix-21 (base)\",\"bert-large-uncased-mix-22 (base)\",\"bert-large-uncased-mix-23 (base)\",\"bert-large-uncased-mix-24 (base)\",\"bert-large-uncased-mix-01 (base)\",\"bert-large-uncased-mix-02 (base)\",\"bert-large-uncased-mix-03 (base)\",\"bert-large-uncased-mix-04 (base)\",\"bert-large-uncased-mix-05 (base)\",\"bert-large-uncased-mix-06 (base)\",\"bert-large-uncased-mix-07 (base)\",\"bert-large-uncased-mix-08 (base)\",\"bert-large-uncased-mix-09 (base)\",\"bert-large-uncased-mix-10 (base)\",\"bert-large-uncased-mix-11 (base)\",\"bert-large-uncased-mix-12 (base)\",\"bert-large-uncased-mix-13 (base)\",\"bert-large-uncased-mix-14 (base)\",\"bert-large-uncased-mix-15 (base)\",\"bert-large-uncased-mix-16 (base)\",\"bert-large-uncased-mix-17 (base)\",\"bert-large-uncased-mix-18 (base)\",\"bert-large-uncased-mix-19 (base)\",\"bert-large-uncased-mix-20 (base)\",\"bert-large-uncased-mix-21 (base)\",\"bert-large-uncased-mix-22 (base)\",\"bert-large-uncased-mix-23 (base)\",\"bert-large-uncased-mix-24 (base)\",\"bert-large-uncased-mix-01 (base)\",\"bert-large-uncased-mix-02 (base)\",\"bert-large-uncased-mix-03 (base)\",\"bert-large-uncased-mix-04 (base)\",\"bert-large-uncased-mix-05 (base)\",\"bert-large-uncased-mix-06 (base)\",\"bert-large-uncased-mix-07 (base)\",\"bert-large-uncased-mix-08 (base)\",\"bert-large-uncased-mix-09 (base)\",\"bert-large-uncased-mix-10 (base)\",\"bert-large-uncased-mix-11 (base)\",\"bert-large-uncased-mix-12 (base)\",\"bert-large-uncased-mix-13 (base)\",\"bert-large-uncased-mix-14 (base)\",\"bert-large-uncased-mix-15 (base)\",\"bert-large-uncased-mix-16 (base)\",\"bert-large-uncased-mix-17 (base)\",\"bert-large-uncased-mix-18 (base)\",\"bert-large-uncased-mix-19 (base)\",\"bert-large-uncased-mix-20 (base)\",\"bert-large-uncased-mix-21 (base)\",\"bert-large-uncased-mix-22 (base)\",\"bert-large-uncased-mix-23 (base)\",\"bert-large-uncased-mix-24 (base)\",\"bert-large-uncased-mix-01 (base)\",\"bert-large-uncased-mix-02 (base)\",\"bert-large-uncased-mix-03 (base)\",\"bert-large-uncased-mix-04 (base)\",\"bert-large-uncased-mix-05 (base)\",\"bert-large-uncased-mix-06 (base)\",\"bert-large-uncased-mix-07 (base)\",\"bert-large-uncased-mix-08 (base)\",\"bert-large-uncased-mix-09 (base)\",\"bert-large-uncased-mix-10 (base)\",\"bert-large-uncased-mix-11 (base)\",\"bert-large-uncased-mix-12 (base)\",\"bert-large-uncased-mix-13 (base)\",\"bert-large-uncased-mix-14 (base)\",\"bert-large-uncased-mix-15 (base)\",\"bert-large-uncased-mix-16 (base)\",\"bert-large-uncased-mix-17 (base)\",\"bert-large-uncased-mix-18 (base)\",\"bert-large-uncased-mix-19 (base)\",\"bert-large-uncased-mix-20 (base)\",\"bert-large-uncased-mix-21 (base)\",\"bert-large-uncased-mix-22 (base)\",\"bert-large-uncased-mix-23 (base)\",\"bert-large-uncased-mix-24 (base)\",\"bert-large-uncased-mix-01 (base)\",\"bert-large-uncased-mix-02 (base)\",\"bert-large-uncased-mix-03 (base)\",\"bert-large-uncased-mix-04 (base)\",\"bert-large-uncased-mix-05 (base)\",\"bert-large-uncased-mix-06 (base)\",\"bert-large-uncased-mix-07 (base)\",\"bert-large-uncased-mix-08 (base)\",\"bert-large-uncased-mix-09 (base)\",\"bert-large-uncased-mix-10 (base)\",\"bert-large-uncased-mix-11 (base)\",\"bert-large-uncased-mix-12 (base)\",\"bert-large-uncased-mix-13 (base)\",\"bert-large-uncased-mix-14 (base)\",\"bert-large-uncased-mix-15 (base)\",\"bert-large-uncased-mix-16 (base)\",\"bert-large-uncased-mix-17 (base)\",\"bert-large-uncased-mix-18 (base)\",\"bert-large-uncased-mix-19 (base)\",\"bert-large-uncased-mix-20 (base)\",\"bert-large-uncased-mix-21 (base)\",\"bert-large-uncased-mix-22 (base)\",\"bert-large-uncased-mix-23 (base)\",\"bert-large-uncased-mix-24 (base)\",\"bert-large-uncased-mix-01 (base)\",\"bert-large-uncased-mix-02 (base)\",\"bert-large-uncased-mix-03 (base)\",\"bert-large-uncased-mix-04 (base)\",\"bert-large-uncased-mix-05 (base)\",\"bert-large-uncased-mix-06 (base)\",\"bert-large-uncased-mix-07 (base)\",\"bert-large-uncased-mix-08 (base)\",\"bert-large-uncased-mix-09 (base)\",\"bert-large-uncased-mix-10 (base)\",\"bert-large-uncased-mix-11 (base)\",\"bert-large-uncased-mix-12 (base)\",\"bert-large-uncased-mix-13 (base)\",\"bert-large-uncased-mix-14 (base)\",\"bert-large-uncased-mix-15 (base)\",\"bert-large-uncased-mix-16 (base)\",\"bert-large-uncased-mix-17 (base)\",\"bert-large-uncased-mix-18 (base)\",\"bert-large-uncased-mix-19 (base)\",\"bert-large-uncased-mix-20 (base)\",\"bert-large-uncased-mix-21 (base)\",\"bert-large-uncased-mix-22 (base)\",\"bert-large-uncased-mix-23 (base)\",\"bert-large-uncased-mix-24 (base)\",\"bert-large-uncased-mix-01 (base)\",\"bert-large-uncased-mix-02 (base)\",\"bert-large-uncased-mix-03 (base)\",\"bert-large-uncased-mix-04 (base)\",\"bert-large-uncased-mix-05 (base)\",\"bert-large-uncased-mix-06 (base)\",\"bert-large-uncased-mix-07 (base)\",\"bert-large-uncased-mix-08 (base)\",\"bert-large-uncased-mix-09 (base)\",\"bert-large-uncased-mix-10 (base)\",\"bert-large-uncased-mix-11 (base)\",\"bert-large-uncased-mix-12 (base)\",\"bert-large-uncased-mix-13 (base)\",\"bert-large-uncased-mix-14 (base)\",\"bert-large-uncased-mix-15 (base)\",\"bert-large-uncased-mix-16 (base)\",\"bert-large-uncased-mix-17 (base)\",\"bert-large-uncased-mix-18 (base)\",\"bert-large-uncased-mix-19 (base)\",\"bert-large-uncased-mix-20 (base)\",\"bert-large-uncased-mix-21 (base)\",\"bert-large-uncased-mix-22 (base)\",\"bert-large-uncased-mix-23 (base)\",\"bert-large-uncased-mix-24 (base)\"],\"display_row\":[\"coref-ontonotes-conll-1\",\"coref-ontonotes-conll-1\",\"coref-ontonotes-conll-1\",\"coref-ontonotes-conll-1\",\"coref-ontonotes-conll-1\",\"coref-ontonotes-conll-1\",\"coref-ontonotes-conll-1\",\"coref-ontonotes-conll-1\",\"coref-ontonotes-conll-1\",\"coref-ontonotes-conll-1\",\"coref-ontonotes-conll-1\",\"coref-ontonotes-conll-1\",\"coref-ontonotes-conll-1\",\"coref-ontonotes-conll-1\",\"coref-ontonotes-conll-1\",\"coref-ontonotes-conll-1\",\"coref-ontonotes-conll-1\",\"coref-ontonotes-conll-1\",\"coref-ontonotes-conll-1\",\"coref-ontonotes-conll-1\",\"coref-ontonotes-conll-1\",\"coref-ontonotes-conll-1\",\"coref-ontonotes-conll-1\",\"coref-ontonotes-conll-1\",\"dep-labeling-ewt-_micro_avg_\",\"dep-labeling-ewt-_micro_avg_\",\"dep-labeling-ewt-_micro_avg_\",\"dep-labeling-ewt-_micro_avg_\",\"dep-labeling-ewt-_micro_avg_\",\"dep-labeling-ewt-_micro_avg_\",\"dep-labeling-ewt-_micro_avg_\",\"dep-labeling-ewt-_micro_avg_\",\"dep-labeling-ewt-_micro_avg_\",\"dep-labeling-ewt-_micro_avg_\",\"dep-labeling-ewt-_micro_avg_\",\"dep-labeling-ewt-_micro_avg_\",\"dep-labeling-ewt-_micro_avg_\",\"dep-labeling-ewt-_micro_avg_\",\"dep-labeling-ewt-_micro_avg_\",\"dep-labeling-ewt-_micro_avg_\",\"dep-labeling-ewt-_micro_avg_\",\"dep-labeling-ewt-_micro_avg_\",\"dep-labeling-ewt-_micro_avg_\",\"dep-labeling-ewt-_micro_avg_\",\"dep-labeling-ewt-_micro_avg_\",\"dep-labeling-ewt-_micro_avg_\",\"dep-labeling-ewt-_micro_avg_\",\"dep-labeling-ewt-_micro_avg_\",\"ner-ontonotes-_micro_avg_\",\"ner-ontonotes-_micro_avg_\",\"ner-ontonotes-_micro_avg_\",\"ner-ontonotes-_micro_avg_\",\"ner-ontonotes-_micro_avg_\",\"ner-ontonotes-_micro_avg_\",\"ner-ontonotes-_micro_avg_\",\"ner-ontonotes-_micro_avg_\",\"ner-ontonotes-_micro_avg_\",\"ner-ontonotes-_micro_avg_\",\"ner-ontonotes-_micro_avg_\",\"ner-ontonotes-_micro_avg_\",\"ner-ontonotes-_micro_avg_\",\"ner-ontonotes-_micro_avg_\",\"ner-ontonotes-_micro_avg_\",\"ner-ontonotes-_micro_avg_\",\"ner-ontonotes-_micro_avg_\",\"ner-ontonotes-_micro_avg_\",\"ner-ontonotes-_micro_avg_\",\"ner-ontonotes-_micro_avg_\",\"ner-ontonotes-_micro_avg_\",\"ner-ontonotes-_micro_avg_\",\"ner-ontonotes-_micro_avg_\",\"ner-ontonotes-_micro_avg_\",\"nonterminal-ontonotes-_micro_avg_\",\"nonterminal-ontonotes-_micro_avg_\",\"nonterminal-ontonotes-_micro_avg_\",\"nonterminal-ontonotes-_micro_avg_\",\"nonterminal-ontonotes-_micro_avg_\",\"nonterminal-ontonotes-_micro_avg_\",\"nonterminal-ontonotes-_micro_avg_\",\"nonterminal-ontonotes-_micro_avg_\",\"nonterminal-ontonotes-_micro_avg_\",\"nonterminal-ontonotes-_micro_avg_\",\"nonterminal-ontonotes-_micro_avg_\",\"nonterminal-ontonotes-_micro_avg_\",\"nonterminal-ontonotes-_micro_avg_\",\"nonterminal-ontonotes-_micro_avg_\",\"nonterminal-ontonotes-_micro_avg_\",\"nonterminal-ontonotes-_micro_avg_\",\"nonterminal-ontonotes-_micro_avg_\",\"nonterminal-ontonotes-_micro_avg_\",\"nonterminal-ontonotes-_micro_avg_\",\"nonterminal-ontonotes-_micro_avg_\",\"nonterminal-ontonotes-_micro_avg_\",\"nonterminal-ontonotes-_micro_avg_\",\"nonterminal-ontonotes-_micro_avg_\",\"nonterminal-ontonotes-_micro_avg_\",\"pos-ontonotes-_micro_avg_\",\"pos-ontonotes-_micro_avg_\",\"pos-ontonotes-_micro_avg_\",\"pos-ontonotes-_micro_avg_\",\"pos-ontonotes-_micro_avg_\",\"pos-ontonotes-_micro_avg_\",\"pos-ontonotes-_micro_avg_\",\"pos-ontonotes-_micro_avg_\",\"pos-ontonotes-_micro_avg_\",\"pos-ontonotes-_micro_avg_\",\"pos-ontonotes-_micro_avg_\",\"pos-ontonotes-_micro_avg_\",\"pos-ontonotes-_micro_avg_\",\"pos-ontonotes-_micro_avg_\",\"pos-ontonotes-_micro_avg_\",\"pos-ontonotes-_micro_avg_\",\"pos-ontonotes-_micro_avg_\",\"pos-ontonotes-_micro_avg_\",\"pos-ontonotes-_micro_avg_\",\"pos-ontonotes-_micro_avg_\",\"pos-ontonotes-_micro_avg_\",\"pos-ontonotes-_micro_avg_\",\"pos-ontonotes-_micro_avg_\",\"pos-ontonotes-_micro_avg_\",\"rel-semeval-_clean_micro_\",\"rel-semeval-_clean_micro_\",\"rel-semeval-_clean_micro_\",\"rel-semeval-_clean_micro_\",\"rel-semeval-_clean_micro_\",\"rel-semeval-_clean_micro_\",\"rel-semeval-_clean_micro_\",\"rel-semeval-_clean_micro_\",\"rel-semeval-_clean_micro_\",\"rel-semeval-_clean_micro_\",\"rel-semeval-_clean_micro_\",\"rel-semeval-_clean_micro_\",\"rel-semeval-_clean_micro_\",\"rel-semeval-_clean_micro_\",\"rel-semeval-_clean_micro_\",\"rel-semeval-_clean_micro_\",\"rel-semeval-_clean_micro_\",\"rel-semeval-_clean_micro_\",\"rel-semeval-_clean_micro_\",\"rel-semeval-_clean_micro_\",\"rel-semeval-_clean_micro_\",\"rel-semeval-_clean_micro_\",\"rel-semeval-_clean_micro_\",\"rel-semeval-_clean_micro_\",\"spr1-_micro_avg_\",\"spr1-_micro_avg_\",\"spr1-_micro_avg_\",\"spr1-_micro_avg_\",\"spr1-_micro_avg_\",\"spr1-_micro_avg_\",\"spr1-_micro_avg_\",\"spr1-_micro_avg_\",\"spr1-_micro_avg_\",\"spr1-_micro_avg_\",\"spr1-_micro_avg_\",\"spr1-_micro_avg_\",\"spr1-_micro_avg_\",\"spr1-_micro_avg_\",\"spr1-_micro_avg_\",\"spr1-_micro_avg_\",\"spr1-_micro_avg_\",\"spr1-_micro_avg_\",\"spr1-_micro_avg_\",\"spr1-_micro_avg_\",\"spr1-_micro_avg_\",\"spr1-_micro_avg_\",\"spr1-_micro_avg_\",\"spr1-_micro_avg_\",\"srl-conll2012-_clean_micro_\",\"srl-conll2012-_clean_micro_\",\"srl-conll2012-_clean_micro_\",\"srl-conll2012-_clean_micro_\",\"srl-conll2012-_clean_micro_\",\"srl-conll2012-_clean_micro_\",\"srl-conll2012-_clean_micro_\",\"srl-conll2012-_clean_micro_\",\"srl-conll2012-_clean_micro_\",\"srl-conll2012-_clean_micro_\",\"srl-conll2012-_clean_micro_\",\"srl-conll2012-_clean_micro_\",\"srl-conll2012-_clean_micro_\",\"srl-conll2012-_clean_micro_\",\"srl-conll2012-_clean_micro_\",\"srl-conll2012-_clean_micro_\",\"srl-conll2012-_clean_micro_\",\"srl-conll2012-_clean_micro_\",\"srl-conll2012-_clean_micro_\",\"srl-conll2012-_clean_micro_\",\"srl-conll2012-_clean_micro_\",\"srl-conll2012-_clean_micro_\",\"srl-conll2012-_clean_micro_\",\"srl-conll2012-_clean_micro_\"],\"exp_layer\":[9.471179711705389,9.471179711705389,9.471179711705389,9.471179711705389,9.471179711705389,9.471179711705389,9.471179711705389,9.471179711705389,9.471179711705389,9.471179711705389,9.471179711705389,9.471179711705389,9.471179711705389,9.471179711705389,9.471179711705389,9.471179711705389,9.471179711705389,9.471179711705389,9.471179711705389,9.471179711705389,9.471179711705389,9.471179711705389,9.471179711705389,9.471179711705389,5.691932390197615,5.691932390197615,5.691932390197615,5.691932390197615,5.691932390197615,5.691932390197615,5.691932390197615,5.691932390197615,5.691932390197615,5.691932390197615,5.691932390197615,5.691932390197615,5.691932390197615,5.691932390197615,5.691932390197615,5.691932390197615,5.691932390197615,5.691932390197615,5.691932390197615,5.691932390197615,5.691932390197615,5.691932390197615,5.691932390197615,5.691932390197615,4.644666882875676,4.644666882875676,4.644666882875676,4.644666882875676,4.644666882875676,4.644666882875676,4.644666882875676,4.644666882875676,4.644666882875676,4.644666882875676,4.644666882875676,4.644666882875676,4.644666882875676,4.644666882875676,4.644666882875676,4.644666882875676,4.644666882875676,4.644666882875676,4.644666882875676,4.644666882875676,4.644666882875676,4.644666882875676,4.644666882875676,4.644666882875676,3.792980575634427,3.792980575634427,3.792980575634427,3.792980575634427,3.792980575634427,3.792980575634427,3.792980575634427,3.792980575634427,3.792980575634427,3.792980575634427,3.792980575634427,3.792980575634427,3.792980575634427,3.792980575634427,3.792980575634427,3.792980575634427,3.792980575634427,3.792980575634427,3.792980575634427,3.792980575634427,3.792980575634427,3.792980575634427,3.792980575634427,3.792980575634427,3.386439579545165,3.386439579545165,3.386439579545165,3.386439579545165,3.386439579545165,3.386439579545165,3.386439579545165,3.386439579545165,3.386439579545165,3.386439579545165,3.386439579545165,3.386439579545165,3.386439579545165,3.386439579545165,3.386439579545165,3.386439579545165,3.386439579545165,3.386439579545165,3.386439579545165,3.386439579545165,3.386439579545165,3.386439579545165,3.386439579545165,3.386439579545165,9.40046847774628,9.40046847774628,9.40046847774628,9.40046847774628,9.40046847774628,9.40046847774628,9.40046847774628,9.40046847774628,9.40046847774628,9.40046847774628,9.40046847774628,9.40046847774628,9.40046847774628,9.40046847774628,9.40046847774628,9.40046847774628,9.40046847774628,9.40046847774628,9.40046847774628,9.40046847774628,9.40046847774628,9.40046847774628,9.40046847774628,9.40046847774628,9.928992732451892,9.928992732451892,9.928992732451892,9.928992732451892,9.928992732451892,9.928992732451892,9.928992732451892,9.928992732451892,9.928992732451892,9.928992732451892,9.928992732451892,9.928992732451892,9.928992732451892,9.928992732451892,9.928992732451892,9.928992732451892,9.928992732451892,9.928992732451892,9.928992732451892,9.928992732451892,9.928992732451892,9.928992732451892,9.928992732451892,9.928992732451892,6.536649198760027,6.536649198760027,6.536649198760027,6.536649198760027,6.536649198760027,6.536649198760027,6.536649198760027,6.536649198760027,6.536649198760027,6.536649198760027,6.536649198760027,6.536649198760027,6.536649198760027,6.536649198760027,6.536649198760027,6.536649198760027,6.536649198760027,6.536649198760027,6.536649198760027,6.536649198760027,6.536649198760027,6.536649198760027,6.536649198760027,6.536649198760027],\"exp_name\":[\"bert-large-uncased-mix-01-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-02-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-03-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-04-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-05-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-06-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-07-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-08-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-09-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-10-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-11-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-12-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-13-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-14-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-15-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-16-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-17-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-18-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-19-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-20-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-21-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-22-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-23-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-24-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-01-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-02-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-03-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-04-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-05-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-06-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-07-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-08-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-09-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-10-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-11-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-12-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-13-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-14-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-15-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-16-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-17-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-18-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-19-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-20-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-21-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-22-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-23-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-24-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-01-edges-ner-ontonotes\",\"bert-large-uncased-mix-02-edges-ner-ontonotes\",\"bert-large-uncased-mix-03-edges-ner-ontonotes\",\"bert-large-uncased-mix-04-edges-ner-ontonotes\",\"bert-large-uncased-mix-05-edges-ner-ontonotes\",\"bert-large-uncased-mix-06-edges-ner-ontonotes\",\"bert-large-uncased-mix-07-edges-ner-ontonotes\",\"bert-large-uncased-mix-08-edges-ner-ontonotes\",\"bert-large-uncased-mix-09-edges-ner-ontonotes\",\"bert-large-uncased-mix-10-edges-ner-ontonotes\",\"bert-large-uncased-mix-11-edges-ner-ontonotes\",\"bert-large-uncased-mix-12-edges-ner-ontonotes\",\"bert-large-uncased-mix-13-edges-ner-ontonotes\",\"bert-large-uncased-mix-14-edges-ner-ontonotes\",\"bert-large-uncased-mix-15-edges-ner-ontonotes\",\"bert-large-uncased-mix-16-edges-ner-ontonotes\",\"bert-large-uncased-mix-17-edges-ner-ontonotes\",\"bert-large-uncased-mix-18-edges-ner-ontonotes\",\"bert-large-uncased-mix-19-edges-ner-ontonotes\",\"bert-large-uncased-mix-20-edges-ner-ontonotes\",\"bert-large-uncased-mix-21-edges-ner-ontonotes\",\"bert-large-uncased-mix-22-edges-ner-ontonotes\",\"bert-large-uncased-mix-23-edges-ner-ontonotes\",\"bert-large-uncased-mix-24-edges-ner-ontonotes\",\"bert-large-uncased-mix-01-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-02-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-03-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-04-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-05-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-06-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-07-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-08-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-09-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-10-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-11-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-12-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-13-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-14-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-15-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-16-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-17-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-18-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-19-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-20-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-21-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-22-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-23-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-24-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-01-edges-pos-ontonotes\",\"bert-large-uncased-mix-02-edges-pos-ontonotes\",\"bert-large-uncased-mix-03-edges-pos-ontonotes\",\"bert-large-uncased-mix-04-edges-pos-ontonotes\",\"bert-large-uncased-mix-05-edges-pos-ontonotes\",\"bert-large-uncased-mix-06-edges-pos-ontonotes\",\"bert-large-uncased-mix-07-edges-pos-ontonotes\",\"bert-large-uncased-mix-08-edges-pos-ontonotes\",\"bert-large-uncased-mix-09-edges-pos-ontonotes\",\"bert-large-uncased-mix-10-edges-pos-ontonotes\",\"bert-large-uncased-mix-11-edges-pos-ontonotes\",\"bert-large-uncased-mix-12-edges-pos-ontonotes\",\"bert-large-uncased-mix-13-edges-pos-ontonotes\",\"bert-large-uncased-mix-14-edges-pos-ontonotes\",\"bert-large-uncased-mix-15-edges-pos-ontonotes\",\"bert-large-uncased-mix-16-edges-pos-ontonotes\",\"bert-large-uncased-mix-17-edges-pos-ontonotes\",\"bert-large-uncased-mix-18-edges-pos-ontonotes\",\"bert-large-uncased-mix-19-edges-pos-ontonotes\",\"bert-large-uncased-mix-20-edges-pos-ontonotes\",\"bert-large-uncased-mix-21-edges-pos-ontonotes\",\"bert-large-uncased-mix-22-edges-pos-ontonotes\",\"bert-large-uncased-mix-23-edges-pos-ontonotes\",\"bert-large-uncased-mix-24-edges-pos-ontonotes\",\"bert-large-uncased-mix-01-edges-rel-semeval\",\"bert-large-uncased-mix-02-edges-rel-semeval\",\"bert-large-uncased-mix-03-edges-rel-semeval\",\"bert-large-uncased-mix-04-edges-rel-semeval\",\"bert-large-uncased-mix-05-edges-rel-semeval\",\"bert-large-uncased-mix-06-edges-rel-semeval\",\"bert-large-uncased-mix-07-edges-rel-semeval\",\"bert-large-uncased-mix-08-edges-rel-semeval\",\"bert-large-uncased-mix-09-edges-rel-semeval\",\"bert-large-uncased-mix-10-edges-rel-semeval\",\"bert-large-uncased-mix-11-edges-rel-semeval\",\"bert-large-uncased-mix-12-edges-rel-semeval\",\"bert-large-uncased-mix-13-edges-rel-semeval\",\"bert-large-uncased-mix-14-edges-rel-semeval\",\"bert-large-uncased-mix-15-edges-rel-semeval\",\"bert-large-uncased-mix-16-edges-rel-semeval\",\"bert-large-uncased-mix-17-edges-rel-semeval\",\"bert-large-uncased-mix-18-edges-rel-semeval\",\"bert-large-uncased-mix-19-edges-rel-semeval\",\"bert-large-uncased-mix-20-edges-rel-semeval\",\"bert-large-uncased-mix-21-edges-rel-semeval\",\"bert-large-uncased-mix-22-edges-rel-semeval\",\"bert-large-uncased-mix-23-edges-rel-semeval\",\"bert-large-uncased-mix-24-edges-rel-semeval\",\"bert-large-uncased-mix-01-edges-spr1\",\"bert-large-uncased-mix-02-edges-spr1\",\"bert-large-uncased-mix-03-edges-spr1\",\"bert-large-uncased-mix-04-edges-spr1\",\"bert-large-uncased-mix-05-edges-spr1\",\"bert-large-uncased-mix-06-edges-spr1\",\"bert-large-uncased-mix-07-edges-spr1\",\"bert-large-uncased-mix-08-edges-spr1\",\"bert-large-uncased-mix-09-edges-spr1\",\"bert-large-uncased-mix-10-edges-spr1\",\"bert-large-uncased-mix-11-edges-spr1\",\"bert-large-uncased-mix-12-edges-spr1\",\"bert-large-uncased-mix-13-edges-spr1\",\"bert-large-uncased-mix-14-edges-spr1\",\"bert-large-uncased-mix-15-edges-spr1\",\"bert-large-uncased-mix-16-edges-spr1\",\"bert-large-uncased-mix-17-edges-spr1\",\"bert-large-uncased-mix-18-edges-spr1\",\"bert-large-uncased-mix-19-edges-spr1\",\"bert-large-uncased-mix-20-edges-spr1\",\"bert-large-uncased-mix-21-edges-spr1\",\"bert-large-uncased-mix-22-edges-spr1\",\"bert-large-uncased-mix-23-edges-spr1\",\"bert-large-uncased-mix-24-edges-spr1\",\"bert-large-uncased-mix-01-edges-srl-conll2012\",\"bert-large-uncased-mix-02-edges-srl-conll2012\",\"bert-large-uncased-mix-03-edges-srl-conll2012\",\"bert-large-uncased-mix-04-edges-srl-conll2012\",\"bert-large-uncased-mix-05-edges-srl-conll2012\",\"bert-large-uncased-mix-06-edges-srl-conll2012\",\"bert-large-uncased-mix-07-edges-srl-conll2012\",\"bert-large-uncased-mix-08-edges-srl-conll2012\",\"bert-large-uncased-mix-09-edges-srl-conll2012\",\"bert-large-uncased-mix-10-edges-srl-conll2012\",\"bert-large-uncased-mix-11-edges-srl-conll2012\",\"bert-large-uncased-mix-12-edges-srl-conll2012\",\"bert-large-uncased-mix-13-edges-srl-conll2012\",\"bert-large-uncased-mix-14-edges-srl-conll2012\",\"bert-large-uncased-mix-15-edges-srl-conll2012\",\"bert-large-uncased-mix-16-edges-srl-conll2012\",\"bert-large-uncased-mix-17-edges-srl-conll2012\",\"bert-large-uncased-mix-18-edges-srl-conll2012\",\"bert-large-uncased-mix-19-edges-srl-conll2012\",\"bert-large-uncased-mix-20-edges-srl-conll2012\",\"bert-large-uncased-mix-21-edges-srl-conll2012\",\"bert-large-uncased-mix-22-edges-srl-conll2012\",\"bert-large-uncased-mix-23-edges-srl-conll2012\",\"bert-large-uncased-mix-24-edges-srl-conll2012\"],\"exp_type\":[\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\"],\"f1_errn95\":{\"__ndarray__\":\"YbyXW15qhD83mxUglT6EP6TjVjSnIoQ/egk/W3Z+gz+hkn2X90+DPyGni5UxWYM/yDjWnvkigz+3V8b+XrCCP6sQ/SP1jII/tCQwnJgigj/E279c13yBP5MZxbC0cYE/6sViBDS9gD838IN551WAP96jb/mnKn8/Hlst8aiHfj8qbxpEFZl9Pz6hqemOonw/JDrU/oORfD/Z/zWnZvd8P6l5aKu4qXw/envGuChifD8An6bUVHF8P1xVcqClrnw/tfFHZpDvbz/efdJWmvluP8eWhMMOE24/HvVgdf+taz+ODjvul0RrP13RAjFaUms/uUE5MPHHaj9L7gKADpNqP3zY2gYzO2o/Wb1i+KQhaT8HXFxs5qdnP2usiuD8kWY/ugMy7vbXZT993WUhUA9lPx2EYV40J2U/FAU5yduhZD+sORxUwNZkPz3L9Yvo12Q/K7Gh7Z5rZD8A1qMTTYpkP8fHKEvidGQ/x2OT5b6uZD8FxZbPv8ZkP7vF21h/t2Q/NWaSgEXoaz9ZcqU5MP9rP6PZpqtbqWs/XEIZJPnKaj/uNZ+jiJBpP2BMDpcGo2k/3kr9uNkdaT+dUvQ8p+RoP85V7qKym2g/5I/0fXhXaD/N3PyrYk1nPyStC2aVJGc/oc0iBcejZj/eomBdBWJmP2A+xYlP12U/2WmTH9VDZT9ydYJq7mtlPwf+fg6hJGU/2x97mc0FZT/Q30HLnxBlP1O41pD/UmU/iCg0REgIZT9cLItEVBBlPxKAthfSa2U/XoZcAwvlWT9bPWy9iVJZP5NlQfwmF1k/1wH9MbuUVz8G1u7Qcz1XP1nEpmsOMlc/ZSDnr+xVVz/isiZ5oBtXP4egxcw/3FY/YDqjA+NVVj+j6P6e19ZVPzDi4QGxWlU/1mnvGzyIVT/8ShLO6ZpVP9xVbObFjVU//Us4IuxKVT/z7w+vmKRVP5cQCQ0qM1U/xEV7AE1OVT+OZxf/3DxVP3kXTERpkFU/Nx6MMCGjVT+p3MJf5YRVPyN56PwneVU/+CmZCEh/UD8hnKjZ9gpOP0NeIxzd4Uw/UVqDBdaeSj+Lgvvu4aRJPwrC/XeAGUk/JgFo5SdRSD9crpyUHeBHP+iwPIGCsEc/Lwr3kscoRz+u1YvdRD1GP8Q+t2Q4hkU/eiAqREHlRD+Q8tGpj/hEP6oFeIpFUkU/JefzlmsIRT9ubzk+tlFFP2bprwPUP0U/Qy3TCsgQRT9KF6vRNDtFPye6bh1qPEU/YfxrBV9FRT/YhRjvI01FP8QXNK3PU0U/imG10137nz96kvjPZhyfP8yWEBieiJ8/pTsu6p7Xnj+eSWPUyjSeP4o/3vicnZ0/0datB50qnT/j9Cvee+WcPxp6H94FrZw/EjSnb5ZinD+ZS7M5jeabP4XSXDXaPJs/Q52zr4rpmj+zaLb5yfKaP3RMtsbII5o/T5Iw3X9bmT/Ac3SfzKCYP/d4duaHqZg/poHpxxppmD9h+inv+vSXP7qblP7a/pc/8BgtthpGlz8kezGKqnCXPwW/sJsZ/ZY/7W0xEZqbhT8Jc1OB5Y2FP5dglwYdboU/VKW5C7cchT/QS6HKlgeFP4EAQseH64Q/xqKeaGn1hD/Le9wM386EP4hZQX5uqoQ//z0HB4F+hD8b7to5GT+EPx+Vy6HuJIQ/1RAg00EzhD8lxTI/QhuEP65+bv7A/oM/7tduyPSmgz8LN5e5xaWDP82jC/M+jYM/uc6VpH1+gz99De5zSG2DPxCoS8MDL4M/E2iWicM1gz/PPP0+6SqDP/MYEB3iHIM/NKFILzC2ZT/k1Lcy/O9jP6GBP09Q4WQ/8l/Ksms5Yz+IX9oC2ihjP7W3Vg0yGmM/lHhnMnmfYj/tf9F0kd1hP1D/HSqoJmI/uF3kgVuQYT+QyCwFtMNgP5z3hw9NjGA/hpLc09P5Xz8OPavsFF9fP4ag8vb2ZF8//8zuSkb2Xj/p+iz9vzZfP+22DrTqmV8/D9xeIdUxXz9sHOBcjM1eP0MslZLV514/MZ7JVSQqXz9pAChUcvVeP+P36luDMV8/\",\"dtype\":\"float64\",\"shape\":[192]},\"f1_score\":{\"__ndarray__\":\"p0NJbJox6j+9Z07rtVfqP1PseqgNaOo/HKZ+X1TS6j+MMJnNS+/qP0WrgUxD7Oo/GzbqltcL6z9dxYU7VkrrP4nsI+WSZOs/ndvXyIyc6z84W0n2ufLrP818ndEd/+s/Lm/Z0uZU7D8TL3K6xIvsP1nqigaL5ew/YRWK2c4J7T/aLhLiRD7tP0IvuJm0b+0/H2sgaJVw7T8VIb1lCF3tPxNyKuAXbu0/1Ekl11957T/yp2OHCXjtP1qcpWasa+0/+66CKpE47D/OCkjTxH7sPx+0+9SQuOw/QcBYKVBK7T9A2Z086WHtP54aNGcGW+0/lbI8rzh37T8PQF+mXoPtP1FcA17Qk+0/+7mdAvXM7T9HDi4SvRTuP0z8coaBR+4/2PVjVzJj7j+pYfLAnoLuP8sV6hm6fu4/zWRoVgeT7j/rLb5I8ozuP/axCNkujO4//xwAuXqa7j/UF1O/h5fuPwwD9TIfmu4/H5iM7i2T7j9eHu97FI/uP5XlmwrXkO4/DXFB5fre7T82R3GCVdrtP/ZxHFZY6u0/isgy5aoN7j8QCKf1kz3uPwoME9ztOu4/ZPhQRlFN7j9hgf95Q1XuP2r6c7iVXe4/GuE+1WBo7j/wdEmnh4zuP8FSk6WFkO4/reHvIhig7j/rLOjDTaruP7eTG2l6u+4/BgKQQj7M7j8rpCc7kcbuP1j77fHqz+4/dwajPpvT7j9+rDobZ9HuP90+iqopye4/UhgAk3bR7j8osd/uL9DuP4+pfJEmxO4/iwDrqaRw6T8CrKgDJ8vpPyWIfP148ek/etiwH3/O6j9m9LgWRvzqPy+3YkriAes/ExFHO6Xv6j8sCuXlKg3rP8fZZhpRK+s/OF7wNOVq6z8LsGv9E6XrP1O3oDFM0+s/pNTigxXK6z9+JtZlAsPrP72gAcyiy+s/6KMAT6Dl6z/h0C3D2rzrP6kduaWP6+s/5qp22xfi6z+Revg2u+nrPx3Y7gn1yes//BLRWE276z/DJEODp8vrPzr9rOWW0+s/OKTj0M9U7T+Hc48vaNHtP1pwwwHQ/u0/wmrxj0JR7j+2zdv803HuP1ILmCxAg+4/z6a8bfGb7j9hovBMZqnuP43C6SP8ru4/g1JfSnK+7j+xM0FHW9juP0a6Kji36+4/qrJL/Fv87j90IRCUSfruPxtY3gjd8O4/6hHXqq347j81+ZkZPvHuP0adVA8B8+4/7EckneL37j/SoX+TdvPuP0ofe0xf8+4/VEJbCWXy7j+y/pqJtPHuP9Yv5qwS8e4/RB64inam5D/kE4ucSPHkP2CNifRA5eQ/VM/hHaHL5T9dFh3O0gzmPzIdYcRBquY/WI4aV44a5z8RBNev21rnP35OWMM7o+c/V3zFV3zF5z9yr4JZUg7oP8nSDmTjfug/PIjvIL6D6D8RdVqXAK/oPwxmmqRNEek/aF4Pu/qT6T8R1bg2ePrpP7To+AhyDOo/V7PzVKlQ6j/bALa3I5PqP8uU4icboOo/Te07F+Tq6j9ydGiSf8HqP/4H5GEp7+o/Ia/yfEj/6D+yNzNpCxzpP1nPMVnPMek/WhfImXdk6T881z1JvHPpP11xo29niuk/enYyLbma6T97sK3p37HpP2A/NNsS0Ok/R2io9y/s6T+HwMtW1/bpP5YWcTCDI+o/BhLgnC8h6j8/OExvVTfqP+4MxCOdSeo/Xtk3mml46j/sDcK2jYjqP7V/8pJnnOo/7z7cAgqj6j/Ib9P/57LqP+YvM6Jkzeo/ou6sGerO6j/+lI1M9drqP/nCVgpjyuo/DpL7WS0r6j9Km3635DXrPx8ADkkWpuo/uGT8L9eR6z8ZCKtQ957rP2DfQLs7pes/EJ5d+UDp6z9iaBgf+EnsP/42oKxqJew/UkIFq5lp7D9L1QsJK8vsPwLH61sY1+w/mD4bfJUY7T+uVPHwSTrtP7CZY81SN+0/tytSaoVQ7T8HuM7CjUTtP8X9eIb1Mu0/P1o1p45D7T+QbcEEyFXtP7CAQse8Ve0/ANgXt09E7T99yFW4IFPtP1P0yyhPQ+0/\",\"dtype\":\"float64\",\"shape\":[192]},\"fn_count\":{\"__ndarray__\":\"AAAAAACEkUAAAAAAAACSQAAAAAAAQJFAAAAAAABQj0AAAAAAAHiOQAAAAAAAOI9AAAAAAADYjUAAAAAAACiLQAAAAAAAUItAAAAAAAAgiUAAAAAAAHiGQAAAAAAAAIdAAAAAAAAYhEAAAAAAAGCDQAAAAAAAeIFAAAAAAADAgEAAAAAAADCAQAAAAAAAQH5AAAAAAACwfEAAAAAAANB9QAAAAAAAEH5AAAAAAAAgfEAAAAAAAOB8QAAAAAAAQH1AAAAAAACKrkAAAAAAAAKsQAAAAAAAIKpAAAAAAAAypUAAAAAAAGKkQAAAAAAA0KRAAAAAAAD0o0AAAAAAAICjQAAAAAAADKNAAAAAAAAeoUAAAAAAAFydQAAAAAAAsJlAAAAAAABImEAAAAAAAESWQAAAAAAAjJZAAAAAAAA8lUAAAAAAAFiVQAAAAAAAfJVAAAAAAADYlEAAAAAAAMyUQAAAAAAAuJRAAAAAAADolEAAAAAAAECVQAAAAAAAOJVAAAAAAAC0mEAAAAAAABSZQAAAAAAA9JdAAAAAAABIlkAAAAAAAPCTQAAAAAAADJRAAAAAAABkk0AAAAAAABCTQAAAAAAACJNAAAAAAABMkkAAAAAAAIyQQAAAAAAAnJBAAAAAAAAMkEAAAAAAAHiOQAAAAAAA2IxAAAAAAACgi0AAAAAAAHiMQAAAAAAASItAAAAAAADoikAAAAAAAHCLQAAAAAAAWIxAAAAAAAC4i0AAAAAAAPCLQAAAAAAAaI1AAAAAAOCw7kAAAAAAgP7sQAAAAACg+etAAAAAAIDv5kAAAAAA4NDlQAAAAACg7uVAAAAAACD55UAAAAAAYCDlQAAAAADAHeRAAAAAAICh4kAAAAAAIGbhQAAAAABAet9AAAAAAMDg4EAAAAAAoC/hQAAAAADgl+FAAAAAAMBp4EAAAAAAgBDhQAAAAABArd9AAAAAAGA+4EAAAAAAYBrgQAAAAABgeeFAAAAAACDa4EAAAAAAwNvgQAAAAACAHuFAAAAAAMAK2kAAAAAAwHHVQAAAAAAAkdNAAAAAAADhz0AAAAAAAHfNQAAAAAAASMxAAAAAAIAbykAAAAAAgPnIQAAAAACAfMhAAAAAAIB1x0AAAAAAgKLFQAAAAAAAMsRAAAAAAICJwkAAAAAAAP7CQAAAAAAADMRAAAAAAAAgw0AAAAAAgKDDQAAAAAAAm8NAAAAAAAAYw0AAAAAAAJfDQAAAAAAAjcNAAAAAAAC1w0AAAAAAgJrDQAAAAACAjcNAAAAAAABQe0AAAAAAALB7QAAAAAAAQHtAAAAAAACweEAAAAAAANB4QAAAAAAAMHdAAAAAAAAAdkAAAAAAAFB1QAAAAAAAUHRAAAAAAABAdEAAAAAAAMBzQAAAAAAAwHJAAAAAAAAgc0AAAAAAAFByQAAAAAAAsHFAAAAAAABgcEAAAAAAAOBuQAAAAAAAIG5AAAAAAAAgbEAAAAAAAMBqQAAAAAAAAGpAAAAAAAAgaUAAAAAAAGBqQAAAAAAAwGlAAAAAAAAslUAAAAAAAJSVQAAAAAAADJVAAAAAAACwk0AAAAAAAGyTQAAAAAAAJJNAAAAAAAAolEAAAAAAAGyTQAAAAAAALJNAAAAAAACEkkAAAAAAAOiQQAAAAAAASJFAAAAAAAC0kUAAAAAAALSRQAAAAAAAWJFAAAAAAAAEkEAAAAAAAJyQQAAAAAAAmJBAAAAAAABEkEAAAAAAAGiQQAAAAAAASI5AAAAAAADgjkAAAAAAADiPQAAAAAAAGI1AAAAAAABZ0kAAAAAAgEDOQAAAAADABNFAAAAAAAA5zEAAAAAAALXLQAAAAACAm8tAAAAAAACnyUAAAAAAABTHQAAAAAAAF8hAAAAAAIB6xkAAAAAAAKvDQAAAAAAA7sNAAAAAAAD5wUAAAAAAAPbAQAAAAAAAIsFAAAAAAABKwEAAAAAAgJDAQAAAAAAA58BAAAAAAICzwEAAAAAAgEzAQAAAAAAAAsBAAAAAAAC5wEAAAAAAABPAQAAAAACAucBA\",\"dtype\":\"float64\",\"shape\":[192]},\"fp_count\":{\"__ndarray__\":\"AAAAAADgjUAAAAAAAHiKQAAAAAAAwItAAAAAAACoikAAAAAAAFCKQAAAAAAAcIlAAAAAAACwiUAAAAAAABiKQAAAAAAAiIhAAAAAAACQiEAAAAAAAKCHQAAAAAAAUIZAAAAAAACwhUAAAAAAANiDQAAAAAAAwIFAAAAAAADYgEAAAAAAAPB9QAAAAAAAsHtAAAAAAABwfUAAAAAAAAB+QAAAAAAAEHxAAAAAAABAfUAAAAAAAIB8QAAAAAAAQH1AAAAAAACkm0AAAAAAALiaQAAAAAAAaJlAAAAAAABclkAAAAAAAOCVQAAAAAAAkJVAAAAAAAC4lEAAAAAAAIyUQAAAAAAA8JNAAAAAAACgkkAAAAAAAPSQQAAAAAAA+I9AAAAAAACQjUAAAAAAAMCLQAAAAAAA6ItAAAAAAADAikAAAAAAALiLQAAAAAAAkItAAAAAAAAgikAAAAAAANCKQAAAAAAAeIpAAAAAAABwi0AAAAAAAICLQAAAAAAAOItAAAAAAAAckUAAAAAAABCRQAAAAAAACJFAAAAAAAAIkEAAAAAAAICNQAAAAAAAsI1AAAAAAAAojEAAAAAAAJiLQAAAAAAAUIpAAAAAAAAwikAAAAAAADCIQAAAAAAAaIdAAAAAAAAghkAAAAAAAECGQAAAAAAAQIVAAAAAAADgg0AAAAAAAOCDQAAAAAAAqINAAAAAAAB4g0AAAAAAAECDQAAAAAAAmINAAAAAAADwgkAAAAAAAOiCQAAAAAAAQINAAAAAAGC64UAAAAAAAAHhQAAAAABgIeFAAAAAAIBy4EAAAAAAAGDgQAAAAACgBOBAAAAAAOCa4EAAAAAA4LjgQAAAAADgB+FAAAAAAKDI4EAAAAAA4F7gQAAAAABA6+BAAAAAAICE30AAAAAAADXfQAAAAADAi91AAAAAAMDO3kAAAAAAQPTfQAAAAACA4d9AAAAAAAB+30AAAAAAAFPfQAAAAAAA+d1AAAAAACBP4EAAAAAAgHXfQAAAAACAOt5AAAAAAIDB1EAAAAAAAN7QQAAAAAAAWc9AAAAAAIB0y0AAAAAAgGbJQAAAAACALshAAAAAAAD/xkAAAAAAgErGQAAAAACABMZAAAAAAIDoxEAAAAAAACnDQAAAAACA78FAAAAAAIBUwUAAAAAAACTBQAAAAAAAXMFAAAAAAIA6wUAAAAAAAMHBQAAAAACAhsFAAAAAAABgwUAAAAAAAHrBQAAAAAAAiMFAAAAAAACBwUAAAAAAgLbBQAAAAACA28FAAAAAAABgYUAAAAAAAABaQAAAAAAAgF5AAAAAAADgYEAAAAAAAABcQAAAAAAAwFxAAAAAAABAXUAAAAAAAIBdQAAAAAAAQF9AAAAAAABAXUAAAAAAAIBbQAAAAAAAQFpAAAAAAACAV0AAAAAAAMBZQAAAAAAAAFdAAAAAAABAVkAAAAAAAABVQAAAAAAAAFZAAAAAAABAV0AAAAAAAMBWQAAAAAAAAFhAAAAAAACAVUAAAAAAAMBUQAAAAAAAgFNAAAAAAAAgk0AAAAAAAKyRQAAAAAAA4JFAAAAAAACEkkAAAAAAAHySQAAAAAAARJJAAAAAAABIkEAAAAAAALyQQAAAAAAARJBAAAAAAAB0kEAAAAAAAISSQAAAAAAAuJBAAAAAAAAskEAAAAAAACCPQAAAAAAAKI9AAAAAAAAwkEAAAAAAANCNQAAAAAAAyIxAAAAAAABYjUAAAAAAABiMQAAAAAAAMI5AAAAAAABIjUAAAAAAACiMQAAAAAAAAJBAAAAAAABywUAAAAAAAJC9QAAAAAAAo79AAAAAAAAWu0AAAAAAAFO7QAAAAAAADbtAAAAAAABaukAAAAAAALy4QAAAAAAAQrlAAAAAAACUt0AAAAAAAFy2QAAAAAAAurRAAAAAAAAHtEAAAAAAAKizQAAAAAAAfrNAAAAAAABqs0AAAAAAAMCzQAAAAAAAZ7RAAAAAAACCs0AAAAAAAPWyQAAAAAAAprNAAAAAAABls0AAAAAAALWzQAAAAAAAebNA\",\"dtype\":\"float64\",\"shape\":[192]},\"headroom_frac\":[0.11924885819738537,0.03996721039058294,0.017140421649633177,0.11146254929550593,0.03038005576537206,-0.0031810205357324533,0.03312049975352221,0.06554423838211923,0.02751723148026277,0.05870779732206643,0.09038194987617033,0.012994533931393479,0.0899711835062617,0.057544055426013214,0.0941554286364117,0.038034739061359575,0.05502101674630216,0.05184888037111926,0.0009209019126946332,-0.02050474977806233,0.017893088720822545,0.011831623054286953,-0.001402548109784854,-0.012967003881791192,0.2552961451987966,0.08571666388070989,0.07056984300753828,0.17795750809220312,0.028813297520848605,-0.008407960805112571,0.03442798399467113,0.014833374333912536,0.02007851533913474,0.06977179598644982,0.08764532430371803,0.06198679296932539,0.033810481044065,0.038367950323117364,-0.004753551766156646,0.0247882900172759,-0.007426600182279491,-0.00093197779573694,0.017455773577464858,-0.0036010119373959273,0.003164343846574142,-0.008476982213772787,-0.005005107139037365,0.002148873429032305,0.4791982211336487,-0.009891106145895561,0.0340871052865562,0.07520020654437398,0.10199998036717652,-0.005639610582429029,0.03914809319882639,0.016917214660451055,0.0177155281538795,0.02297859496756056,0.07696540660112836,0.008499427846274655,0.033152979036450446,0.02173578613491763,0.036563897265948664,0.035692553434345645,-0.012083724412743479,0.019906658225229384,0.007852611018777643,-0.004691581164156769,-0.01754286793889932,0.017671690507210475,-0.0027168640452855117,-0.02562503503298699,0.43393080373117005,0.08069473862517886,0.034164924189038576,0.19705666713813655,0.04081324252297465,0.005001685717589329,-0.01626063414168284,0.026320767613806483,0.026880014569003505,0.05668416484190521,0.05187341178951657,0.041207585195417534,-0.008214686744818612,-0.006307464967222522,0.007691196972660172,0.02317212566698648,-0.03635028836649214,0.04164188588817257,-0.008441174648693595,0.0068097961739946354,-0.028328744863199494,-0.013065756438097056,0.014578921690911177,0.007074678879016351,0.3784284742308631,0.1828476667355257,0.0666346555308144,0.12099473483139221,0.04779518822915531,0.025568237353502887,0.03623728251225715,0.01974825874378391,0.008196938642824872,0.022690440103526475,0.03802426441659814,0.028410415478405303,0.024424942293711224,-0.0030406763304073217,-0.013830330429953717,0.01146895508684831,-0.010912080276386219,0.0025850134239233467,0.007163492216400578,-0.006489543235589698,-0.0001337192172299884,-0.001434364809713496,-0.0010115825845617107,-0.0009276700694607807,0.16221498189598205,0.03896546992230503,-0.006265014174623446,0.11997591758797638,0.03395204362609319,0.08198897667938805,0.058483648736245904,0.033487470970807134,0.037692043645149255,0.01783806788879979,0.03793176021336738,0.05862284787089483,0.002528150688210505,0.0225289374879972,0.0511935388585347,0.06805410860647258,0.05337522991053467,0.00936147400547985,0.03552589384242925,0.03462064620541661,0.0067527124357650865,0.03894686462089184,-0.021556712297086854,0.023780632679324145,0.07247782669231503,0.056082018969539724,0.04244075766653939,0.09877673197230072,0.02977159547370385,0.04420186458920255,0.03182159173573683,0.04514331750093816,0.058885546990404526,0.05481900795319719,0.020773669739524464,0.08710461877813493,-0.0045368655638756035,0.043185960148158196,0.0356449582877082,0.09125322407314639,0.0314734063674154,0.03870737444621078,0.012936313692669019,0.030939546172008905,0.05164691316155298,0.002966565950091014,0.023484003296992732,-0.03231217680545297,0.04427504907852022,0.3144658977427871,-0.1695519225694335,0.2779602169777315,0.015475620765603718,0.007388990299869476,0.08019797792426021,0.11403008811614881,-0.04309647767899822,0.08039057846486555,0.11503543473906527,0.01406248617789181,0.07721303638837286,0.03973896689669341,-0.0034965449250411143,0.0297090482565448,-0.014109716236869104,-0.020744562443314917,0.01956981024831055,0.021486838349607178,-5.168215563501218e-05,-0.020545647839889162,0.017468822980427713,-0.018650709311520762],\"index\":[14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417],\"kl_unif\":{\"__ndarray__\":\"smln+9gk4z+yaWf72CTjP7JpZ/vYJOM/smln+9gk4z+yaWf72CTjP7JpZ/vYJOM/smln+9gk4z+yaWf72CTjP7JpZ/vYJOM/smln+9gk4z+yaWf72CTjP7JpZ/vYJOM/smln+9gk4z+yaWf72CTjP7JpZ/vYJOM/smln+9gk4z+yaWf72CTjP7JpZ/vYJOM/smln+9gk4z+yaWf72CTjP7JpZ/vYJOM/smln+9gk4z+yaWf72CTjP7JpZ/vYJOM/U3dL5sBn8j9Td0vmwGfyP1N3S+bAZ/I/U3dL5sBn8j9Td0vmwGfyP1N3S+bAZ/I/U3dL5sBn8j9Td0vmwGfyP1N3S+bAZ/I/U3dL5sBn8j9Td0vmwGfyP1N3S+bAZ/I/U3dL5sBn8j9Td0vmwGfyP1N3S+bAZ/I/U3dL5sBn8j9Td0vmwGfyP1N3S+bAZ/I/U3dL5sBn8j9Td0vmwGfyP1N3S+bAZ/I/U3dL5sBn8j9Td0vmwGfyP1N3S+bAZ/I/KvtYfCS7+T8q+1h8JLv5Pyr7WHwku/k/KvtYfCS7+T8q+1h8JLv5Pyr7WHwku/k/KvtYfCS7+T8q+1h8JLv5Pyr7WHwku/k/KvtYfCS7+T8q+1h8JLv5Pyr7WHwku/k/KvtYfCS7+T8q+1h8JLv5Pyr7WHwku/k/KvtYfCS7+T8q+1h8JLv5Pyr7WHwku/k/KvtYfCS7+T8q+1h8JLv5Pyr7WHwku/k/KvtYfCS7+T8q+1h8JLv5Pyr7WHwku/k/1wcJs1Mx+T/XBwmzUzH5P9cHCbNTMfk/1wcJs1Mx+T/XBwmzUzH5P9cHCbNTMfk/1wcJs1Mx+T/XBwmzUzH5P9cHCbNTMfk/1wcJs1Mx+T/XBwmzUzH5P9cHCbNTMfk/1wcJs1Mx+T/XBwmzUzH5P9cHCbNTMfk/1wcJs1Mx+T/XBwmzUzH5P9cHCbNTMfk/1wcJs1Mx+T/XBwmzUzH5P9cHCbNTMfk/1wcJs1Mx+T/XBwmzUzH5P9cHCbNTMfk/PGxpRu6G+T88bGlG7ob5PzxsaUbuhvk/PGxpRu6G+T88bGlG7ob5PzxsaUbuhvk/PGxpRu6G+T88bGlG7ob5PzxsaUbuhvk/PGxpRu6G+T88bGlG7ob5PzxsaUbuhvk/PGxpRu6G+T88bGlG7ob5PzxsaUbuhvk/PGxpRu6G+T88bGlG7ob5PzxsaUbuhvk/PGxpRu6G+T88bGlG7ob5PzxsaUbuhvk/PGxpRu6G+T88bGlG7ob5PzxsaUbuhvk/IbZb25sJ4D8htlvbmwngPyG2W9ubCeA/IbZb25sJ4D8htlvbmwngPyG2W9ubCeA/IbZb25sJ4D8htlvbmwngPyG2W9ubCeA/IbZb25sJ4D8htlvbmwngPyG2W9ubCeA/IbZb25sJ4D8htlvbmwngPyG2W9ubCeA/IbZb25sJ4D8htlvbmwngPyG2W9ubCeA/IbZb25sJ4D8htlvbmwngPyG2W9ubCeA/IbZb25sJ4D8htlvbmwngPyG2W9ubCeA/Zn7/NR5c1T9mfv81HlzVP2Z+/zUeXNU/Zn7/NR5c1T9mfv81HlzVP2Z+/zUeXNU/Zn7/NR5c1T9mfv81HlzVP2Z+/zUeXNU/Zn7/NR5c1T9mfv81HlzVP2Z+/zUeXNU/Zn7/NR5c1T9mfv81HlzVP2Z+/zUeXNU/Zn7/NR5c1T9mfv81HlzVP2Z+/zUeXNU/Zn7/NR5c1T9mfv81HlzVP2Z+/zUeXNU/Zn7/NR5c1T9mfv81HlzVP2Z+/zUeXNU/3Qo2TbTp9D/dCjZNtOn0P90KNk206fQ/3Qo2TbTp9D/dCjZNtOn0P90KNk206fQ/3Qo2TbTp9D/dCjZNtOn0P90KNk206fQ/3Qo2TbTp9D/dCjZNtOn0P90KNk206fQ/3Qo2TbTp9D/dCjZNtOn0P90KNk206fQ/3Qo2TbTp9D/dCjZNtOn0P90KNk206fQ/3Qo2TbTp9D/dCjZNtOn0P90KNk206fQ/3Qo2TbTp9D/dCjZNtOn0P90KNk206fQ/\",\"dtype\":\"float64\",\"shape\":[192]},\"label\":[\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\"],\"layer_num\":[\"01\",\"02\",\"03\",\"04\",\"05\",\"06\",\"07\",\"08\",\"09\",\"10\",\"11\",\"12\",\"13\",\"14\",\"15\",\"16\",\"17\",\"18\",\"19\",\"20\",\"21\",\"22\",\"23\",\"24\",\"01\",\"02\",\"03\",\"04\",\"05\",\"06\",\"07\",\"08\",\"09\",\"10\",\"11\",\"12\",\"13\",\"14\",\"15\",\"16\",\"17\",\"18\",\"19\",\"20\",\"21\",\"22\",\"23\",\"24\",\"01\",\"02\",\"03\",\"04\",\"05\",\"06\",\"07\",\"08\",\"09\",\"10\",\"11\",\"12\",\"13\",\"14\",\"15\",\"16\",\"17\",\"18\",\"19\",\"20\",\"21\",\"22\",\"23\",\"24\",\"01\",\"02\",\"03\",\"04\",\"05\",\"06\",\"07\",\"08\",\"09\",\"10\",\"11\",\"12\",\"13\",\"14\",\"15\",\"16\",\"17\",\"18\",\"19\",\"20\",\"21\",\"22\",\"23\",\"24\",\"01\",\"02\",\"03\",\"04\",\"05\",\"06\",\"07\",\"08\",\"09\",\"10\",\"11\",\"12\",\"13\",\"14\",\"15\",\"16\",\"17\",\"18\",\"19\",\"20\",\"21\",\"22\",\"23\",\"24\",\"01\",\"02\",\"03\",\"04\",\"05\",\"06\",\"07\",\"08\",\"09\",\"10\",\"11\",\"12\",\"13\",\"14\",\"15\",\"16\",\"17\",\"18\",\"19\",\"20\",\"21\",\"22\",\"23\",\"24\",\"01\",\"02\",\"03\",\"04\",\"05\",\"06\",\"07\",\"08\",\"09\",\"10\",\"11\",\"12\",\"13\",\"14\",\"15\",\"16\",\"17\",\"18\",\"19\",\"20\",\"21\",\"22\",\"23\",\"24\",\"01\",\"02\",\"03\",\"04\",\"05\",\"06\",\"07\",\"08\",\"09\",\"10\",\"11\",\"12\",\"13\",\"14\",\"15\",\"16\",\"17\",\"18\",\"19\",\"20\",\"21\",\"22\",\"23\",\"24\"],\"lex_score\":[0.804675649147854,0.804675649147854,0.804675649147854,0.804675649147854,0.804675649147854,0.804675649147854,0.804675649147854,0.804675649147854,0.804675649147854,0.804675649147854,0.804675649147854,0.804675649147854,0.804675649147854,0.804675649147854,0.804675649147854,0.804675649147854,0.804675649147854,0.804675649147854,0.804675649147854,0.804675649147854,0.804675649147854,0.804675649147854,0.804675649147854,0.804675649147854,0.8563817514420556,0.8563817514420556,0.8563817514420556,0.8563817514420556,0.8563817514420556,0.8563817514420556,0.8563817514420556,0.8563817514420556,0.8563817514420556,0.8563817514420556,0.8563817514420556,0.8563817514420556,0.8563817514420556,0.8563817514420556,0.8563817514420556,0.8563817514420556,0.8563817514420556,0.8563817514420556,0.8563817514420556,0.8563817514420556,0.8563817514420556,0.8563817514420556,0.8563817514420556,0.8563817514420556,0.905993125093409,0.905993125093409,0.905993125093409,0.905993125093409,0.905993125093409,0.905993125093409,0.905993125093409,0.905993125093409,0.905993125093409,0.905993125093409,0.905993125093409,0.905993125093409,0.905993125093409,0.905993125093409,0.905993125093409,0.905993125093409,0.905993125093409,0.905993125093409,0.905993125093409,0.905993125093409,0.905993125093409,0.905993125093409,0.905993125093409,0.905993125093409,0.7355877588962386,0.7355877588962386,0.7355877588962386,0.7355877588962386,0.7355877588962386,0.7355877588962386,0.7355877588962386,0.7355877588962386,0.7355877588962386,0.7355877588962386,0.7355877588962386,0.7355877588962386,0.7355877588962386,0.7355877588962386,0.7355877588962386,0.7355877588962386,0.7355877588962386,0.7355877588962386,0.7355877588962386,0.7355877588962386,0.7355877588962386,0.7355877588962386,0.7355877588962386,0.7355877588962386,0.8851251582672498,0.8851251582672498,0.8851251582672498,0.8851251582672498,0.8851251582672498,0.8851251582672498,0.8851251582672498,0.8851251582672498,0.8851251582672498,0.8851251582672498,0.8851251582672498,0.8851251582672498,0.8851251582672498,0.8851251582672498,0.8851251582672498,0.8851251582672498,0.8851251582672498,0.8851251582672498,0.8851251582672498,0.8851251582672498,0.8851251582672498,0.8851251582672498,0.8851251582672498,0.8851251582672498,0.6072974644403215,0.6072974644403215,0.6072974644403215,0.6072974644403215,0.6072974644403215,0.6072974644403215,0.6072974644403215,0.6072974644403215,0.6072974644403215,0.6072974644403215,0.6072974644403215,0.6072974644403215,0.6072974644403215,0.6072974644403215,0.6072974644403215,0.6072974644403215,0.6072974644403215,0.6072974644403215,0.6072974644403215,0.6072974644403215,0.6072974644403215,0.6072974644403215,0.6072974644403215,0.6072974644403215,0.7766251728907331,0.7766251728907331,0.7766251728907331,0.7766251728907331,0.7766251728907331,0.7766251728907331,0.7766251728907331,0.7766251728907331,0.7766251728907331,0.7766251728907331,0.7766251728907331,0.7766251728907331,0.7766251728907331,0.7766251728907331,0.7766251728907331,0.7766251728907331,0.7766251728907331,0.7766251728907331,0.7766251728907331,0.7766251728907331,0.7766251728907331,0.7766251728907331,0.7766251728907331,0.7766251728907331,0.8131866690279881,0.8131866690279881,0.8131866690279881,0.8131866690279881,0.8131866690279881,0.8131866690279881,0.8131866690279881,0.8131866690279881,0.8131866690279881,0.8131866690279881,0.8131866690279881,0.8131866690279881,0.8131866690279881,0.8131866690279881,0.8131866690279881,0.8131866690279881,0.8131866690279881,0.8131866690279881,0.8131866690279881,0.8131866690279881,0.8131866690279881,0.8131866690279881,0.8131866690279881,0.8131866690279881],\"max_layer_score\":[0.9210662080825451,0.9210662080825451,0.9210662080825451,0.9210662080825451,0.9210662080825451,0.9210662080825451,0.9210662080825451,0.9210662080825451,0.9210662080825451,0.9210662080825451,0.9210662080825451,0.9210662080825451,0.9210662080825451,0.9210662080825451,0.9210662080825451,0.9210662080825451,0.9210662080825451,0.9210662080825451,0.9210662080825451,0.9210662080825451,0.9210662080825451,0.9210662080825451,0.9210662080825451,0.9210662080825451,0.9563573468484775,0.9563573468484775,0.9563573468484775,0.9563573468484775,0.9563573468484775,0.9563573468484775,0.9563573468484775,0.9563573468484775,0.9563573468484775,0.9563573468484775,0.9563573468484775,0.9563573468484775,0.9563573468484775,0.9563573468484775,0.9563573468484775,0.9563573468484775,0.9563573468484775,0.9563573468484775,0.9563573468484775,0.9563573468484775,0.9563573468484775,0.9563573468484775,0.9563573468484775,0.9563573468484775,0.9633308623671856,0.9633308623671856,0.9633308623671856,0.9633308623671856,0.9633308623671856,0.9633308623671856,0.9633308623671856,0.9633308623671856,0.9633308623671856,0.9633308623671856,0.9633308623671856,0.9633308623671856,0.9633308623671856,0.9633308623671856,0.9633308623671856,0.9633308623671856,0.9633308623671856,0.9633308623671856,0.9633308623671856,0.9633308623671856,0.9633308623671856,0.9633308623671856,0.9633308623671856,0.9633308623671856,0.8725050198344678,0.8725050198344678,0.8725050198344678,0.8725050198344678,0.8725050198344678,0.8725050198344678,0.8725050198344678,0.8725050198344678,0.8725050198344678,0.8725050198344678,0.8725050198344678,0.8725050198344678,0.8725050198344678,0.8725050198344678,0.8725050198344678,0.8725050198344678,0.8725050198344678,0.8725050198344678,0.8725050198344678,0.8725050198344678,0.8725050198344678,0.8725050198344678,0.8725050198344678,0.8725050198344678,0.9683055808687488,0.9683055808687488,0.9683055808687488,0.9683055808687488,0.9683055808687488,0.9683055808687488,0.9683055808687488,0.9683055808687488,0.9683055808687488,0.9683055808687488,0.9683055808687488,0.9683055808687488,0.9683055808687488,0.9683055808687488,0.9683055808687488,0.9683055808687488,0.9683055808687488,0.9683055808687488,0.9683055808687488,0.9683055808687488,0.9683055808687488,0.9683055808687488,0.9683055808687488,0.9683055808687488,0.8416945373467113,0.8416945373467113,0.8416945373467113,0.8416945373467113,0.8416945373467113,0.8416945373467113,0.8416945373467113,0.8416945373467113,0.8416945373467113,0.8416945373467113,0.8416945373467113,0.8416945373467113,0.8416945373467113,0.8416945373467113,0.8416945373467113,0.8416945373467113,0.8416945373467113,0.8416945373467113,0.8416945373467113,0.8416945373467113,0.8416945373467113,0.8416945373467113,0.8416945373467113,0.8416945373467113,0.8392282958199357,0.8392282958199357,0.8392282958199357,0.8392282958199357,0.8392282958199357,0.8392282958199357,0.8392282958199357,0.8392282958199357,0.8392282958199357,0.8392282958199357,0.8392282958199357,0.8392282958199357,0.8392282958199357,0.8392282958199357,0.8392282958199357,0.8392282958199357,0.8392282958199357,0.8392282958199357,0.8392282958199357,0.8392282958199357,0.8392282958199357,0.8392282958199357,0.8392282958199357,0.8392282958199357,0.916721352852095,0.916721352852095,0.916721352852095,0.916721352852095,0.916721352852095,0.916721352852095,0.916721352852095,0.916721352852095,0.916721352852095,0.916721352852095,0.916721352852095,0.916721352852095,0.916721352852095,0.916721352852095,0.916721352852095,0.916721352852095,0.916721352852095,0.916721352852095,0.916721352852095,0.916721352852095,0.916721352852095,0.916721352852095,0.916721352852095,0.916721352852095],\"num_epochs\":{\"__ndarray__\":\"AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/\",\"dtype\":\"float64\",\"shape\":[192]},\"num_steps\":{\"__ndarray__\":\"AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/\",\"dtype\":\"float64\",\"shape\":[192]},\"precision\":{\"__ndarray__\":\"UK7HUKyT6j97cjRNqRLrP9qWc7ao6uo/OgAzgcEs6z+cbcvEH0DrP9u1a9euXes/qUHpNwFd6z/vNfDS6V7rP5EQVoYom+s/krPPhoqn6z8zyoPAEtzrPzS/DDS/DOw/JXaRAFM17D96Bw5VWoLsP3QdtYLR3+w/+hRkceMH7T8VBpEblVftP18gu4KAiu0/atK9r89o7T/+mjN9F1vtP4S1d3b4gu0/27Zt27Zt7T/Ui6R28HvtP1qcpWasa+0/TDU9/hqJ7T8rsRBHGqXtP3nSJfyQxu0/H1Y8tAYU7j8f/3lqJyDuP5ZQCiCFJe4/3UfI2ic57j+AA0Gb0D3uP1ZBWFCDS+4/j8BY9wBr7j/x2o9Yd5LuP1oL8t7Jqe4/2Pz03LbD7j+w/bW/9tfuP5NvnbAj1u4/dquBsAbj7j/OX/JY/tjuP6Sydlp92u4/1QE0rr3p7j/HlHpHteLuP59aFw9M5u4/T67YQDbc7j9dwg5OT9vuPxtGp4k43u4/iVFeFoI87j/OByPlIT3uPzR4rVSKP+4/QgPJFsha7j8XzKkww33uP3ztB8RJe+4/0LXLYzWP7j+ALoxfoZbuP+nnu6y8pu4/hvulfx2p7j8dHJRBD8TuP/TTtmvSze4/GDDEgoLe7j8wIv+Lr93uP8QpYWEC6+4/NA8vKN787j/YMAf0hPzuPxg7GVfF/+4/iTc5bEoC7z8GU3171wTvP8o/r6UgAO8/sWasYq8I7z8t8wyp/gjvPwZ62T0NBO8/MkW2mdXq6j84x1SJwyrrPw/xwLkdLus/ypdPKAaL6z+JWmgdBprrP9Qt1fEsrus/HBllJuiK6z8Bm0cYEozrPy30nRijg+s/EfkgD7ef6z+GVM62h8LrPzESLn/fses/ZLywHVTq6z+XaIAhu/DrP6szCDcMHuw/HwpxwMoC7D/XTExLHtzrP1eSbc2i6Os/JeJBtWfw6z8Aonv5a/brPz5mwvhvEuw/orJ5T9fK6z8ftNejMOzrP9Ne6VnZDew/rH14KDic7T+0eV5xGhDuP4EXJ0lRNO4/d70IaM5v7j/t4Xcd/o3uP/OhOmG5n+4/mGqRMpWx7j+9mDUOFbzuP1AGJnMtwO4/fpXQdT/Q7j+zTQRRrunuP7m9C5iR++4/vkLdPNQE7z9Vwv+PSgfvP+u1aGS+A+8/1/JV//4F7z8d2Kn/Yf7uP21UVfqaAe8/Lly/JfMD7z8wrpqaTALvPxK4WTGMAe8/+RosodwB7z/aT0dP+P7uP4doPVn2/O4/mYVKmYVK6T/pw37KRqbqPyZgy5JL9+k/NFo9OF7W6T9A5ijdvrLqP2sZOmC3x+o/TLwfOc3X6j+NBXgDK+LqPwhxMPBmvuo/Po2w3NMI6z/bWe2sdlbrPwGBQWITnes/xvYmBub76z+cuZu5m7nrP3ZOijA3Lew/AfOB7MJi7D8bymsor6HsP4kCk07Ng+w/yYS6dP5o7D97XW1PaobsPwdodzSyYew/yEPwVT6/7D/LLasTwM/sP09+JQbsAO0/gzXqTzdH6T+uTdUZ0KjpPyjPvW+Qo+k/CpRCMueN6T/7inOp4JTpPy+O31lsqek/8Y1HThEp6j9IEGgIpRPqP6kjXXGLOuo/MqMfmF036j9esqUBXb7pPyzEc/XZN+o/40yIlB5Z6j/7K/iZT4bqPySQETOqiuo/zhdFJSty6j9L/v5u2MfqPwLrRPL37uo/TIZgHW3e6j9dGnZHxQvrP62DwxQfz+o/x9hygors6j+YBeDucRTrP1wEk6+uleo/7ACAjU776z+DvR8Ve6/sP7O25qYdYuw/k3zUm9n67D+d51HCe/fsPxuyKGEO/+w/JdEopy8b7T+5XdWo+VDtP+TEH43ZPu0/courzy9x7T8Y2QNUKpztP2mphgO7xO0/w6UIxujd7T/zDkqq9ertPw8OrMSE7u0/w81nq3Dz7T8f4aIc/OntP3R0S7dN2O0/fgNgUKLv7T8jG++G+/7tP7KyDMV/7u0/s2qFRG7y7T8IkAtWyuztP9IF03Jx8O0/\",\"dtype\":\"float64\",\"shape\":[192]},\"precision_errn95\":{\"__ndarray__\":\"24dVEQ0NhD/LolCxjoiDP6iashMToIM/i37jxgcZgz9VQ4ZUcfKCPxrRs+9q14I/JV2te2bCgj+pOiws25WCP49ubkeRRYI/WoUf4i0Tgj+txmND8p+BP/GDuP2jXIE/9/NO5IrzgD+6XtBp32aAP+OVJmdPQX8/dOzhoouPfj/CscMYsSx9P8RP23haKXw/MdVYsY21fD8zarVKKQB9PyKWJqgWS3w/Q1Nx7fGYfD8F0rM1Ol98P1xVcqClrnw/7hItxc0+bD+uJ5odHoFrP066Pe7vsmo/laTVtpW2aD9jWTQoe2NoP07WTldmTGg/yzg9+urKZz+lNcCPgqdnP7pa5V+TTWc/wphGb4JqZj89oH4aekJlP3UeVHgrh2Q/t4PuvS3DYz/01URPwB1jP7CSPCaKLWM/B4An0XzBYj9bI+nFyw9jP1JBJF9ABWM/E4jRJx2KYj+NhlO5JMFiP3bK6y2DpGI/jBpc+jj0Yj+KE0Oxaf1iP6E5VXrB5mI/+84K37P+aT/N06Vg5P5pP+9a711z4mk/IVyP0WMaaT/xziRBHQ1oP2UI1NT6H2g/sbwX4F+IZz+oSlT8001nPzJhLcUM02Y/b/yDKIS5Zj/fEzYkJtNlPxFuRFGKg2U/sSs21a3xZD+23X2JifFkP1fnvmLedmQ/XmKq+4PRYz+FCWHtOdhjP69bC/hvtWM/IsyDZZ2cYz/B85+KGIdjPyav5JOOtmM/AhfROT9kYz/yXAtFOWJjPw48OB2SlmM/1b3EmfyMWD/8uM2SWvJXP6mKPC2azFc/LWmxIOmbVj8Mv9vJfmJWP9wSejhnQlY/iyst7eaAVj/0d9N6TGdWP0DRI564WVY/IO468PMBVj/K92xQ5qRVPzCCdQqFl1U/VfC++JVPVT/4r4TiiEtVP04XvUNV/1Q/tTLW1TUWVT+fGLCPXG5VP6f/LPuMOFU/j3k5DGA0VT8MI2pCryVVP0yi4ZnpElU/ovcxpw6IVT9IAdY/p0tVP7ZqyVjSElU/Zpyny7ilTz+znikNWKxMPwYBXDcpo0s/Zud/H//OST//1iDYMNtIP9vFjQQUSEg/wiLzMwqqRz9KFWJd5ktHP0XgevV9Jkc/ASksTv2VRj+xKFR4LadFP+VWLykf90Q/w+ju0f+URD9KlZ1G6n5EPyy1HkXwpkQ/WjQu91aMRD+AhqLvKdlEPwIy/Ba6uUQ/drSf7U+gRD8PQwO037JEP6QI6HQGukQ/c9FBP7e3RD84MWvDW9NEPwtOAnaJ5kQ/SXk7Nau6nz/vAGn7ngeeP0zol4lP3Z4/7svrLFbknT8ekAmuPrOcP0QSV8aw7Zs/eik3XzRjmz8/o8UY1hObP4gL+YnZ9Jo/oCJeVuF2mj8NifSJFMWZP6H8hkPQ8Jg/KHqmsYhLmD/0XoXBXpeYP4r8eAPFdZc/fT+pbX2hlj9IhGz74M2VPzzjdVkD/5U/SuhWBcT/lT9DdeVkL5KVP/wIZOtI0JU/LmTjUzjalD/dUb87GdSUPzz4FTkzQpQ/D8TlLKZrhT/DJnp5hy2FP0PyYDHoHYU/tYsvHVT9hD+kBgXx/e2EP0NXhCrt0oQ/hiawoY+EhD+k1dsAy36EP2TEsElrUIQ/tr+r75k8hD+uNSJSznKEP1+KZy7IEYQ/0kUkCij/gz/Tt4W6VdCDP+chsq2pv4M/2uurLG6tgz9SjIFPQWSDP7iWBTFyNoM/jkBez0c/gz9chYIn3w2DP6pOqkUQLYM/1TJl0IkUgz9AETOdKOqCPysYq1c+WYM/MkJIdwrzYz+hThc6phliP87YXJvB/WI//MC8jHFRYT/7GS/tSFBhP1LHSHtwPWE/wiITdy7cYD9TfdokdjJgP3F3COhvbmA/6VrY7fGwXz9ztbEoeH5eP5oF50XJpl0/JQvwEv3hXD/JjcEaUHtcPz7le3S8alw/+enMaew3XD+tjJNn03ZcP5514C415lw/DWU6CQhZXD+5eMYmAfNbP0peVtACTlw/gYbmrf1IXD+MbwgdxVlcPzKp387WVFw/\",\"dtype\":\"float64\",\"shape\":[192]},\"pred_pos_count\":{\"__ndarray__\":\"AAAAAAAJtkAAAAAAAH21QAAAAAAA1rVAAAAAAAAZtkAAAAAAACm2QAAAAAAA9bVAAAAAAAAptkAAAAAAAIy2QAAAAAAAVbZAAAAAAACctkAAAAAAANO2QAAAAAAAmLZAAAAAAADhtkAAAAAAAL22QAAAAAAAt7ZAAAAAAACxtkAAAAAAAIe2QAAAAAAAhbZAAAAAAAC6tkAAAAAAALG2QAAAAAAAjrZAAAAAAADAtkAAAAAAAKi2QAAAAAAArrZAAAAAAIBu1kAAAAAAwLDWQAAAAAAA2NZAAAAAAABF10AAAAAAQFfXQAAAAACARNdAAAAAAIBS10AAAAAAQF7XQAAAAAAAY9dAAAAAAMCL10AAAAAAAL/XQAAAAABA6tdAAAAAAIDt10AAAAAAQP/XQAAAAAAA/NdAAAAAAMAH2EAAAAAAwA3YQAAAAABACthAAAAAAAAJ2EAAAAAAQA/YQAAAAADADdhAAAAAAIAS2EAAAAAAgA3YQAAAAADAC9hAAAAAAABn00AAAAAAQGDTQAAAAADAcdNAAAAAAIB800AAAAAAgI3TQAAAAABAjdNAAAAAAICL00AAAAAAQIzTQAAAAACAgtNAAAAAAECN00AAAAAAQJnTQAAAAAAAktNAAAAAAMCQ00AAAAAAwJ7TQAAAAADAo9NAAAAAAICi00AAAAAAwJvTQAAAAACAo9NAAAAAAACl00AAAAAAAJ/TQAAAAACAmtNAAAAAAECa00AAAAAAQJjTQAAAAABAj9NAAAAAAEjnC0EAAAAAiCUMQQAAAADYbgxBAAAAAKiFDUEAAAAAsMgNQQAAAABoqg1BAAAAAFjNDUEAAAAACAsOQQAAAABwXw5BAAAAALCuDkEAAAAAGOMOQQAAAABwcA9BAAAAAEjdDkEAAAAAoL8OQQAAAABocA5BAAAAAFDkDkEAAAAAUN8OQQAAAABwKw9BAAAAABAFD0EAAAAAsAgPQQAAAACwhQ5BAAAAACgCD0EAAAAAqNwOQQAAAACYpA5BAAAAAOBeEUEAAAAAOGoRQQAAAAAsdRFBAAAAABCQEUEAAAAA8JIRQQAAAACokhFBAAAAAJCaEUEAAAAA/J0RQQAAAAC0nxFBAAAAAAyfEUEAAAAAqJ8RQQAAAABgoRFBAAAAAMypEUEAAAAApKQRQQAAAAD0nRFBAAAAAEikEUEAAAAAeKQRQQAAAADQohFBAAAAALSlEUEAAAAAjKIRQQAAAABMoxFBAAAAANShEUEAAAAAVKQRQQAAAADkpRFBAAAAAAC4hEAAAAAAAHCDQAAAAAAAOIRAAAAAAADohUAAAAAAACCFQAAAAAAACIZAAAAAAACwhkAAAAAAABCHQAAAAAAAyIdAAAAAAACQh0AAAAAAAJiHQAAAAAAA8IdAAAAAAABoh0AAAAAAABiIQAAAAAAAEIhAAAAAAACgiEAAAAAAAPCIQAAAAAAAQIlAAAAAAADoiUAAAAAAADCKQAAAAAAAiIpAAAAAAABwikAAAAAAAAiKQAAAAAAACIpAAAAAAADDtkAAAAAAAEy2QAAAAAAAe7ZAAAAAAAD7tkAAAAAAAAq3QAAAAAAADrdAAAAAAABOtkAAAAAAAJq2QAAAAAAAjLZAAAAAAADCtkAAAAAAAK23QAAAAAAAIrdAAAAAAADktkAAAAAAAL22QAAAAAAA1bZAAAAAAABRt0AAAAAAANm2QAAAAAAAubZAAAAAAADgtkAAAAAAAK+2QAAAAAAAQ7dAAAAAAAATt0AAAAAAAOS2QAAAAAAAo7dAAAAAAKBd8UAAAAAAkNbxQAAAAACgfvFAAAAAAODv8UAAAAAAMATyQAAAAAAAA/JAAAAAAGA28kAAAAAA4G7yQAAAAADgVvJAAAAAAJBv8kAAAAAAALbyQAAAAACAk/JAAAAAAPDG8kAAAAAAYOHyQAAAAABA2fJAAAAAAADz8kAAAAAAkO/yQAAAAAAw7/JAAAAAAFDn8kAAAAAAYOvyQAAAAADA//JAAAAAANDk8kAAAAAAkP7yQAAAAAAA5vJA\",\"dtype\":\"float64\",\"shape\":[192]},\"prev_layer_score\":[0.8046756386756897,0.8185550570487976,0.8232068419456482,0.8252018094062805,0.8381749987602234,0.8417109251022339,0.8413406610488892,0.8451955914497375,0.852824330329895,0.8560270667076111,0.8628600835800171,0.8733797073364258,0.8748921751976013,0.8853639960289001,0.8920615911483765,0.9030203819274902,0.9074472784996033,0.9138512015342712,0.9198859333992004,0.9199931025505066,0.9176065325737,0.9196891188621521,0.9210662245750427,0.9209029674530029,0.8563817739486694,0.8819051384925842,0.8904747366905212,0.8975300192832947,0.915321409702301,0.9182020425796509,0.9173614382743835,0.9208033680915833,0.922286331653595,0.9242936968803406,0.9312691688537598,0.9400315880775452,0.9462287425994873,0.9496089816093445,0.9534448385238647,0.9529696106910706,0.9554478526115417,0.9547053575515747,0.9546121954917908,0.9563573598861694,0.9559973478317261,0.9563137292861938,0.9554662108421326,0.9549658298492432,0.9059931039810181,0.9334692358970642,0.9329020977020264,0.9348565936088562,0.939168393611908,0.9450168609619141,0.9446935057640076,0.946938157081604,0.9479081630706787,0.9489239454269409,0.9502415060997009,0.9546545147895813,0.9551418423652649,0.9570427536964417,0.9582890272140503,0.9603855013847351,0.9624320268630981,0.961739182472229,0.9628806114196777,0.963330864906311,0.9630618691444397,0.9620559811592102,0.9630692601203918,0.962913453578949,0.7355877757072449,0.7950003743171692,0.8060488700866699,0.8107266426086426,0.8377071022987366,0.843295156955719,0.8439799547195435,0.8417536020278931,0.845357358455658,0.8490377068519592,0.8567987680435181,0.8639011383056641,0.869543194770813,0.8684184551239014,0.8675548434257507,0.8686078786849976,0.871780514717102,0.8668035268783569,0.8725050091743469,0.8713492751121521,0.8722816705703735,0.8684029579162598,0.866614043712616,0.868610143661499,0.8851251602172852,0.9166030287742615,0.9318123459815979,0.9373550415039062,0.9474194049835205,0.9513950347900391,0.9535217881202698,0.9565359950065613,0.9581786394119263,0.958860456943512,0.9607478380203247,0.963910698890686,0.9662739038467407,0.9683055877685547,0.9680526852607727,0.9669022560119629,0.967856228351593,0.9669485688209534,0.9671635627746582,0.9677594304084778,0.9672196507453918,0.9672085046768188,0.9670891761779785,0.9670050144195557,0.6072974801063538,0.6453201770782471,0.6544535756111145,0.6529850959777832,0.6811071038246155,0.6890653371810913,0.7082833051681519,0.7219917178153992,0.7298410534858704,0.7386759519577026,0.7428571581840515,0.751748263835907,0.7654892802238464,0.7660818696022034,0.7713626027107239,0.7833622097969055,0.7993139028549194,0.8118249177932739,0.8140192031860352,0.8223463892936707,0.8304613828659058,0.8320441842079163,0.8411732316017151,0.8361204266548157,0.7766251564025879,0.7811625003814697,0.7846733927726746,0.7873303294181824,0.79351407289505,0.7953778505325317,0.7981449961662292,0.8001371026039124,0.8029631972312927,0.8066496253013611,0.8100814819335938,0.811381995677948,0.8168350458145142,0.8165510296821594,0.8192545771598816,0.8214860558509827,0.8271988034248352,0.8291691541671753,0.8315923810005188,0.832402229309082,0.8343391418457031,0.8375723958015442,0.8377581238746643,0.8392282724380493,0.8131866455078125,0.8177706599235535,0.850328803062439,0.83277428150177,0.8615527749061584,0.8631550669670105,0.8639200925827026,0.8722233772277832,0.8840294480323792,0.8795674443244934,0.887890636920929,0.8998007774353027,0.9012567400932312,0.9092509746551514,0.913365364074707,0.9130033254623413,0.9160792231559753,0.9146183729171753,0.9124705791473389,0.9144967198371887,0.9167213439941406,0.9167159795761108,0.9145888090133667,0.9163974523544312],\"prev_score_max\":{\"__ndarray__\":\"AAAAIOe/6T8AAABgmjHqPwAAAOC1V+o/AAAAoA1o6j8AAABgVNLqPwAAAMBL7+o/AAAAwEvv6j8AAACg1wvrPwAAAEBWSus/AAAA4JJk6z8AAADAjJzrPwAAAAC68us/AAAA4B3/6z8AAADg5lTsPwAAAMDEi+w/AAAAAIvl7D8AAADgzgntPwAAAOBEPu0/AAAAoLRv7T8AAABglXDtPwAAAGCVcO0/AAAAYJVw7T8AAADgX3ntPwAAAOBfee0/AAAAwHpn6z8AAAAgkTjsPwAAAODEfuw/AAAA4JC47D8AAAAgUErtPwAAAEDpYe0/AAAAQOlh7T8AAACgOHftPwAAAKBeg+0/AAAAYNCT7T8AAAAA9cztPwAAACC9FO4/AAAAgIFH7j8AAABgMmPuPwAAAMCegu4/AAAAwJ6C7j8AAABgB5PuPwAAAGAHk+4/AAAAYAeT7j8AAADAepruPwAAAMB6mu4/AAAAwHqa7j8AAADAepruPwAAAMB6mu4/AAAAQOX97D8AAADg+t7tPwAAAOD63u0/AAAAYFjq7T8AAADgqg3uPwAAAACUPe4/AAAAAJQ97j8AAABAUU3uPwAAAIBDVe4/AAAAwJVd7j8AAADgYGjuPwAAAKCHjO4/AAAAoIWQ7j8AAAAgGKDuPwAAAMBNqu4/AAAAYHq77j8AAABAPszuPwAAAEA+zO4/AAAAAOvP7j8AAABAm9PuPwAAAECb0+4/AAAAQJvT7j8AAABAm9PuPwAAAECb0+4/AAAAYO+J5z8AAACgpHDpPwAAAAAny+k/AAAAAHnx6T8AAAAgf87qPwAAACBG/Oo/AAAAQOIB6z8AAABA4gHrPwAAAOAqDes/AAAAIFEr6z8AAABA5WrrPwAAAAAUpes/AAAAQEzT6z8AAABATNPrPwAAAEBM0+s/AAAAQEzT6z8AAABAoOXrPwAAAECg5es/AAAAoI/r6z8AAACgj+vrPwAAAKCP6+s/AAAAoI/r6z8AAACgj+vrPwAAAKCP6+s/AAAAAPJS7D8AAADgz1TtPwAAACBo0e0/AAAAAND+7T8AAACAQlHuPwAAAADUce4/AAAAIECD7j8AAABg8ZvuPwAAAEBmqe4/AAAAIPyu7j8AAABAcr7uPwAAAEBb2O4/AAAAQLfr7j8AAAAAXPzuPwAAAABc/O4/AAAAAFz87j8AAAAAXPzuPwAAAABc/O4/AAAAAFz87j8AAAAAXPzuPwAAAABc/O4/AAAAAFz87j8AAAAAXPzuPwAAAABc/O4/AAAAIPtu4z8AAACAdqbkPwAAAKBI8eQ/AAAAoEjx5D8AAAAgocvlPwAAAMDSDOY/AAAAwEGq5j8AAABgjhrnPwAAAKDbWuc/AAAAwDuj5z8AAABgfMXnPwAAAGBSDug/AAAAYON+6D8AAAAgvoPoPwAAAKAAr+g/AAAAoE0R6T8AAADA+pPpPwAAAEB4+uk/AAAAAHIM6j8AAABgqVDqPwAAAMAjk+o/AAAAIBug6j8AAAAg5OrqPwAAACDk6uo/AAAAAB3a6D8AAACASP/oPwAAAGALHOk/AAAAYM8x6T8AAACgd2TpPwAAAEC8c+k/AAAAYGeK6T8AAAAguZrpPwAAAODfsek/AAAA4BLQ6T8AAAAAMOzpPwAAAGDX9uk/AAAAQIMj6j8AAABAgyPqPwAAAGBVN+o/AAAAIJ1J6j8AAACgaXjqPwAAAMCNiOo/AAAAoGec6j8AAAAACqPqPwAAAADosuo/AAAAoGTN6j8AAAAg6s7qPwAAAED12uo/AAAAAKAF6j8AAABgLSvqPwAAAMDkNes/AAAAwOQ16z8AAAAg15HrPwAAAGD3nus/AAAAwDul6z8AAAAAQenrPwAAACD4Sew/AAAAIPhJ7D8AAACgmWnsPwAAAAAry+w/AAAAYBjX7D8AAACAlRjtPwAAAABKOu0/AAAAAEo67T8AAABghVDtPwAAAGCFUO0/AAAAYIVQ7T8AAABghVDtPwAAAADIVe0/AAAAAMhV7T8AAAAAyFXtPwAAAADIVe0/\",\"dtype\":\"float64\",\"shape\":[192]},\"real_delta_score\":[0.013879441257917402,0.004651805956420341,0.0019949832561770853,0.012973188412789494,0.003535951670998738,-0.0003702407581366307,0.003854913478508748,0.007628730540243489,0.0032027459523230606,0.006833033344139872,0.010519605663694698,0.0015124410673706956,0.010471796336309458,0.006697584774402521,0.010958802965727377,0.004426884538286768,0.006403926892257106,0.006034720166532503,0.00010718428834255445,-0.0023865592874846575,0.0020825865972845525,0.0013770892203930352,-0.00016324335843065363,-0.0015092368295099856,0.02552338412121402,0.008569574507726108,0.007055262072416357,0.017791407828561145,0.0028806265752692184,-0.0008405908876449875,0.003441958198510009,0.0014829754309192422,0.00200736152590697,0.006975476846320716,0.008762393481853148,0.0061971665344429105,0.003380222973357938,0.003835858678077675,-0.0004752391681167589,0.0024782240535842215,-0.0007424787750688333,-9.31750350343652e-05,0.001745151356686736,-0.0003600133125067906,0.0003163571601318971,-0.0008474913440715826,-0.0005003885662981933,0.0002148349005205441,0.02747614170542223,-0.0005671336455403964,0.0019544774873441195,0.004311809685775048,0.005848448076223534,-0.00032336250990172566,0.0022446630826036262,0.0009699948096050237,0.0010157682989533345,0.0013175406411705115,0.004413022262864885,0.00048733796082711667,0.0019009168018350175,0.0012462807948429022,0.0020964911351403215,0.0020465302514487416,-0.0006928534156666055,0.0011414027393170656,0.00045025094750783534,-0.0002690046481890196,-0.0010058683529091672,0.0010132547474859255,-0.00015577883683715044,-0.0014692815263527281,0.05941261708359613,0.011048502584685815,0.004677767840125413,0.02698045911417002,0.005588037376253352,0.0006848171085261923,-0.0022263614877978677,0.0036037674074740345,0.003680337968767655,0.0077610405887247325,0.007102365457741455,0.005642029694835293,-0.0011247324085661425,-0.0008636008267759454,0.0010530576228330313,0.0031726639764402265,-0.004976981917454881,0.005701492956110887,-0.0011557425120003462,0.0009323786396909783,-0.0038786941524872054,-0.001788927583590283,0.0019961060253524954,0.0009686456541324606,0.03147784041096369,0.015209346190759088,0.005542698806958457,0.01006439317583152,0.003975623955219332,0.0021267767882398037,0.0030142324732994608,0.0016426685079516945,0.0006818248203487309,0.001887400396825334,0.003162874383283776,0.002363190365777923,0.002031677022008127,-0.00025292474215765637,-0.0011504127298819222,0.0009539925309216546,-0.0009076714488512883,0.00021502250903249198,0.0005958623098627491,-0.0005398029488270506,-1.1122820999132088e-05,-0.00011931107103668737,-8.414386688015973e-05,-7.716398841250971e-05,0.038022716937981205,0.009133392094210269,-0.0014685009842487773,0.02812200390187991,0.007958259645146293,0.019217976144238813,0.013708396076661522,0.007849365174594891,0.008834904702282875,0.004181190899440135,0.00889109356420037,0.013741023946374331,0.0005925911211828172,0.005280717002877577,0.011999615660160057,0.01595168385661072,0.012510997656734912,0.0021943021049737332,0.008327165529048552,0.008114978132677364,0.001582816029121914,0.009129031066018478,-0.005052830263922337,0.005574110691895617,0.0045373382940604445,0.0035109095276679714,0.002656923969406866,0.006183731894206845,0.0018637948512387759,0.0027671747625778176,0.0019921310192352326,0.002826112654943258,0.003686419136993635,0.0034318410937509425,0.0013004966003941076,0.005453021157068916,-0.00028402195260857077,0.0027035759719707952,0.002231485705491698,0.0057127368043372595,0.0019703335278200562,0.0024232025207228114,0.0008098536363528863,0.0019369122123800153,0.0032332580535665567,0.00018571629285113467,0.0014701719452714368,-0.0020228431766619037,0.004584003207641407,0.032558127296263395,-0.017554504694995754,0.028778523180469584,0.0016022635029485643,0.0007650167744763792,0.008303272287720986,0.011806069119540519,-0.004461980190427761,0.008323213123796913,0.011910157364277807,0.0014559550602089022,0.007994227309569446,0.004114361373145803,-0.0003620136732909174,0.0030759169179565005,-0.0014608450094321102,-0.002147781713638053,0.0020261541165566,0.0022246330149062743,-5.350895643019271e-06,-0.0021271871530643693,0.0018086290640578762,-0.0019309952916636286],\"real_headroom_frac\":[0.11924885819738537,0.03996721039058294,0.017140421649633177,0.11146254929550593,0.03038005576537206,-0.0031810205357324533,0.03312049975352221,0.06554423838211923,0.02751723148026277,0.05870779732206643,0.09038194987617033,0.012994533931393479,0.0899711835062617,0.057544055426013214,0.0941554286364117,0.038034739061359575,0.05502101674630216,0.05184888037111926,0.0009209019126946332,-0.02050474977806233,0.017893088720822545,0.011831623054286953,-0.001402548109784854,-0.012967003881791192,0.2552961451987966,0.08571666388070989,0.07056984300753828,0.17795750809220312,0.028813297520848605,-0.008407960805112571,0.03442798399467113,0.014833374333912536,0.02007851533913474,0.06977179598644982,0.08764532430371803,0.06198679296932539,0.033810481044065,0.038367950323117364,-0.004753551766156646,0.0247882900172759,-0.007426600182279491,-0.00093197779573694,0.017455773577464858,-0.0036010119373959273,0.003164343846574142,-0.008476982213772787,-0.005005107139037365,0.002148873429032305,0.4791982211336487,-0.009891106145895561,0.0340871052865562,0.07520020654437398,0.10199998036717652,-0.005639610582429029,0.03914809319882639,0.016917214660451055,0.0177155281538795,0.02297859496756056,0.07696540660112836,0.008499427846274655,0.033152979036450446,0.02173578613491763,0.036563897265948664,0.035692553434345645,-0.012083724412743479,0.019906658225229384,0.007852611018777643,-0.004691581164156769,-0.01754286793889932,0.017671690507210475,-0.0027168640452855117,-0.02562503503298699,0.43393080373117005,0.08069473862517886,0.034164924189038576,0.19705666713813655,0.04081324252297465,0.005001685717589329,-0.01626063414168284,0.026320767613806483,0.026880014569003505,0.05668416484190521,0.05187341178951657,0.041207585195417534,-0.008214686744818612,-0.006307464967222522,0.007691196972660172,0.02317212566698648,-0.03635028836649214,0.04164188588817257,-0.008441174648693595,0.0068097961739946354,-0.028328744863199494,-0.013065756438097056,0.014578921690911177,0.007074678879016351,0.3784284742308631,0.1828476667355257,0.0666346555308144,0.12099473483139221,0.04779518822915531,0.025568237353502887,0.03623728251225715,0.01974825874378391,0.008196938642824872,0.022690440103526475,0.03802426441659814,0.028410415478405303,0.024424942293711224,-0.0030406763304073217,-0.013830330429953717,0.01146895508684831,-0.010912080276386219,0.0025850134239233467,0.007163492216400578,-0.006489543235589698,-0.0001337192172299884,-0.001434364809713496,-0.0010115825845617107,-0.0009276700694607807,0.16221498189598205,0.03896546992230503,-0.006265014174623446,0.11997591758797638,0.03395204362609319,0.08198897667938805,0.058483648736245904,0.033487470970807134,0.037692043645149255,0.01783806788879979,0.03793176021336738,0.05862284787089483,0.002528150688210505,0.0225289374879972,0.0511935388585347,0.06805410860647258,0.05337522991053467,0.00936147400547985,0.03552589384242925,0.03462064620541661,0.0067527124357650865,0.03894686462089184,-0.021556712297086854,0.023780632679324145,0.07247782669231503,0.056082018969539724,0.04244075766653939,0.09877673197230072,0.02977159547370385,0.04420186458920255,0.03182159173573683,0.04514331750093816,0.058885546990404526,0.05481900795319719,0.020773669739524464,0.08710461877813493,-0.0045368655638756035,0.043185960148158196,0.0356449582877082,0.09125322407314639,0.0314734063674154,0.03870737444621078,0.012936313692669019,0.030939546172008905,0.05164691316155298,0.002966565950091014,0.023484003296992732,-0.03231217680545297,0.04427504907852022,0.3144658977427871,-0.1695519225694335,0.2779602169777315,0.015475620765603718,0.007388990299869476,0.08019797792426021,0.11403008811614881,-0.04309647767899822,0.08039057846486555,0.11503543473906527,0.01406248617789181,0.07721303638837286,0.03973896689669341,-0.0034965449250411143,0.0297090482565448,-0.014109716236869104,-0.020744562443314917,0.01956981024831055,0.021486838349607178,-5.168215563501218e-05,-0.020545647839889162,0.017468822980427713,-0.018650709311520762],\"recall\":{\"__ndarray__\":\"II//AlLS6T8sbeatlKbpP0rT/HtO6uk/SmzsUTl66j+7BdnVUaDqP6zSze50fuo/SLC364m86j8+J/V84TXrP5t8fXfTLus/h9EIxJeR6z9cJvsghgnsPzLi/aeJ8es/DEhJp8F07D/6WAlaNZXsP8F68M9G6+w/r4uwgroL7T/78fgvICXtP1B68yEZVe0/gM9JPV947T80aQGQ+V7tP7Lg1L5UWe0/pQLuExKF7T8eaWigI3TtP1qcpWasa+0/6CO9zLUE6z9SZFjTaW7rP6ohx84Jves/STENC+aK7D99izX606zsP/DRWHTimuw/C0USgMW+7D8LizeUsdHsPwvRXKid5Ow/SKdcwDI17T/ntdWN/JrtP1las2yn5+0/zM8zGQQF7j8TZ2P/GS/uP2IcsKk6Ke4/73ifOaJE7j+OhkuYWULuPzbhce1pP+4/AbamMMpM7j90Qu++xE3uP96BvVZmT+4/E1CbHXxL7j90n9y0TkTuP2tSYr71RO4/5CZ2Z6+D7T/SGy6XBnrtPwc9BggBl+0/tMOcqBHC7T/hCF++cP7tP/xan4Gf++0/W24d7oYM7j8KeFyk+hTuP0vOt7XIFe4/TTmaTbMo7j+fF5UZx1XuPxxr3vYqVO4/tntKL6hi7j9cPpHylXfuPwIB2LWDjO4//hJNCDac7j+KBvwdWJHuP2Ztw2ejoO4/73Lnz3el7j/CFV88oJ7uPw2zskD0ku4/nBFE7gCb7j+3Y4SxL5juP7X4oRlFhe4/oDmcEM4d6D/2mL4AYo3oP/6pLs5k0Og/Klecwckb6j8/pXDYaWXqPxgeIobFXeo/kRu7DhNb6j8hq9JBwJLqP3vyPhov1eo/FRe/2ds26z/MWaeA3ofrP3Ob5PMJ9es/vHDrESGq6z96ix9a3pXrPx5gxQEXe+s/XI0lW7LI6z8bnH4X3Z3rPwgDDxt97us/7yDSo9bT6z/huw70Fd3rPyvVv6Xsgus/eXuvuNSr6z9eTRDdaavrP72YSnhEmus/Orusq7wO7T8gJ4xSuZPtP4uNf/wKyu0/iF6GyvMy7j/V8c6Y3VXuP1ANmbn7Zu4/ZUfFFmyG7j+DqXY0zpbuPwMWeAPene4/YKiTpLms7j9zXKmdG8fuP0RFIQnt2+4/poeNWujz7j/jMeF5U+3uP1QUB5wS3u4/79aMwGfr7j/WJCxTJeTuP34kVN505O4/Kb+vc9vr7j+bmOW3ruTuP+I60Vc/5e4/xLEi2Pzi7j8BU4YZfOTuP18Mnxw45e4/rXj7UNBy4T/tBmbBqj/hP/dglJNWe+E/6ZQRPtfY4j9UxN+4ysfiP+dbZ3xtpeM/cZnAbWRH5D+llFJKKaXkP08Z4XONLeU/mQF6thM25T/uQ0HLRXrlP5fIz/SpAuY/2FY6ZYTP5T+hIv7GVT7mP4s192CUk+Y/qkOC15dG5z8J4He+dcbnP8hRDU6b+ec/cdabd/+B6D+m0S1UxN/oP2VDw+PpEuk/cJ3xtZVO6T+GivgbV/noP/sT9Wj2I+k/uuMiju646D+7VKLVLpXoP7oPI3juw+g/Nu7kiI076T+1SyVa7VLpP7WupSita+k/N0lk200S6T+1SyVa7VLpP7WjJS7taOk/s4qmuqyi6T8uwWifSzDqPzA9aOFLD+o/sainKyzq6T+xqKcrLOrpPzAnaOzLCeo/rPqpAqt+6j+uKSlra0rqPy4vaWjLS+o/raKpLqto6j8tcWlHS1zqP6ouq2iqy+o/KsbqnIqx6j+riSq7aqLqP6j/KwDq/+o/u4ePNYiT6D+21BqcPOHpP7Hz5qEzHek/snbtw1VK6j+D2ecbCmXqP1SVLMQyauo//0sX53PP6j+vLZ7UxVTrP/ulehhgIOs/xhppq9Nz6z/Aae3rYgXsP/Urk/XU9+s/0mis/S9d7D+G8M+5lZHsP5bP0fGuiOw/vEJUsGG07D+ZWbR1HqbsP0yqQ5WelOw/IKj7ygmf7D/Go2s24LPsP3S+f5rywuw/AeT78eyd7D/p61Eqgr/sP9BdzQzTnew/\",\"dtype\":\"float64\",\"shape\":[192]},\"recall_errn95\":{\"__ndarray__\":\"DsFbVSTLhD/SYu4qXAKFPxkqCVUzrIQ/JAZeNjHogz/EhDpMK7GDP96oE2Yl4oM/xYRgg4OHgz/lFLDlLsuCP3f6RYKP1oI/YPtvuR0ygj86yPU5R1qBP/+8GcD4hoE/5kojNzWIgD96zxKBEkWAP0bG80ohFH8/UasuUMp/fj+htmezqgh+P+IFFYHoH30/mNzVVNRtfD91X/9Mqe58P2Tr4BncCn0/GrPt3i8sfD+0bQadhoN8P1xVcqClrnw/hE3roSdecj/iYQINWblxPx4dZ+SlNnE/BuVFu5d0bz/DTTW5DetuP1Vj4ANENG8/bF0tDL+gbj8DXAUlKlFuPxSRWoJKAG4/7N3r6maYbD/VXxGjKqlqPzSrjDBTEGk/6iTh2SxqaD+0hwjOgHFnP8wBQT7+lGc/u0JUlAjtZj9WhFMeQ/tmP8o3OyV+DWc/btoqAty5Zj+467g2rrNmP1AJHjRdqWY/DahRzRXCZj9x20ifEe9mP+kHLk//6mY/Oa5pzpcfbj8iYBKy71RuP7uvNRNUs20/8ybKPv+5bD+3VvdH+0drP0pIDsHTWWs/gNZM2tjtaj88XSoiBrdqPxMyIuXFsWo/0Moxa9k0aj8XXupIjf5oP/GAr8r1CWk/s6emM1yiaD+gc6lu5AhoPz0hXPuXamc/LofoBnfwZj+MF5I2VkVnPzMgy0h2zWY/UwWoCf2mZj86Y25OZ91mP2kEsunaOGc/lpmtx/f5Zj9llXzvERBnP9E5t571oWc/MFUELPNkWz/8QXp1p91aP4/HZKGgh1o/QPoQAeijWD9pIIV8zilYP/nLA5LANlg/lx0aU047WD/LNWepqdtXP7s8GijfZFc/CX3Y/lusVj+ZlfCAsQlWP/EK0fgvH1U/GgnLkxLCVT8THvs+o+xVP+LJ3K33I1Y/n4U8kayAVT+Ufg8M6ttVP9TiONrJLVU/Uk/Yp3loVT9DdzHDPVRVPycIE0TjE1Y/P44EJHi+VT9YVa2AWr9VPzPF/bty41U/YQRiOQg7UT+QWiGowoxPP8Dl7wSiPk4/019xJy18Sz/ypNdbx3tKP/qwSFiH+Uk/pc1g4sABST8sFwDN4ntIP2JCCvUbQUg/J9RZlDfDRz+Tdr/utttGPwwGHJIoHUY/8yGpRv43RT8q8DtO+3dFPxbKFdYUCUY/HaJN8H6KRT9SxN3R1M9FPyU8aU3izEU/4bW4YCWGRT8Mo/9FvcpFP2f3W6JfxUU/4vHREc3aRT/t2OSvncxFP+MrOFqkxUU/+OhxNI0eoD86NF2m7SKgP+IT5zLCHaA/ZkNVw+Hanz+V+OlAC+GfP8oerMUThZ8/gJ+7Kksxnz+7jKVKMvqeP95H+9AsoZ4/KpIfRUGbnj+fGYViW2qeP2TIBgUyAJ4/YPF0NlUpnj9FgEvZJc6dP/fVNQK7gp0/Ht1Ver7UnD9nsz9Y1UqcP4jLvPlREJw/9xEap3Jqmz8dRPcksu+aP+h0OoSWqZo/BuGS3d1Umj+hEZUz7cyaP/e4Gk61kZo/W0bajGbMhT8ey0tswPGFP0QrWVG8wIU/XCFMZXg8hT9xBoSNbiGFP68H7MxcBIU/tWxp1DdrhT9xBoSNbiGFPx075HGdB4U/Bf6s4hrChD/Br0UTZwyEPyFm/MM5OIQ/2k8G5W1ohD/aTwblbWiEP55YaoRwP4Q/4KdopX+ggz8viEDHCumDP1SDwRcq54M/1OGJDVi/gz8iI1tVgNCDPwt8nKb3MIM/USyoxHFXgz8EJ+Q7a22DP6W52/P54YI/+FH7JsTQZz/mJQ0PlzBmP05CGI2vL2c/MXgVtRqaZT+anKHCNnJlP+FTBIFtamU/OerTTSjMZD+DTutoxOpjPxqPpMDJRWQ/m8gQpz+zYz/KHPjeCp5iPziJRgIduWI/F2iyts3nYT80ItDX9HRhPxfBo/POiGE/bYOHIvQlYT/4eJv1m0ZhPyRDd+gnbmE//yFO1a1WYT890rlGHidhPwCCFWgzBGE/sicBITJZYT8f4SQYNQxhP4pnEqxsWWE/\",\"dtype\":\"float64\",\"shape\":[192]},\"run\":[\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-01-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-02-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-03-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-04-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-05-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-06-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-07-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-08-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-09-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-10-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-11-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-12-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-13-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-14-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-15-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-16-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-17-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-18-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-19-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-20-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-21-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-22-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-23-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-24-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-01-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-02-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-03-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-04-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-05-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-06-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-07-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-08-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-09-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-10-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-11-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-12-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-13-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-14-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-15-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-16-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-17-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-18-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-19-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-20-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-21-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-22-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-23-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-24-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-01-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-02-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-03-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-04-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-05-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-06-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-07-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-08-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-09-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-10-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-11-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-12-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-13-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-14-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-15-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-16-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-17-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-18-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-19-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-20-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-21-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-22-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-23-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-24-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-01-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-02-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-03-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-04-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-05-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-06-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-07-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-08-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-09-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-10-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-11-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-12-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-13-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-14-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-15-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-16-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-17-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-18-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-19-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-20-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-21-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-22-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-23-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-24-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-01-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-02-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-03-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-04-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-05-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-06-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-07-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-08-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-09-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-10-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-11-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-12-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-13-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-14-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-15-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-16-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-17-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-18-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-19-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-20-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-21-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-22-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-23-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-24-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-01-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-02-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-03-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-04-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-05-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-06-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-07-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-08-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-09-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-10-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-11-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-12-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-13-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-14-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-15-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-16-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-17-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-18-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-19-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-20-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-21-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-22-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-23-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-24-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-01-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-02-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-03-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-04-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-05-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-06-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-07-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-08-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-09-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-10-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-11-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-12-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-13-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-14-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-15-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-16-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-17-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-18-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-19-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-20-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-21-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-22-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-23-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-24-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-01-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-02-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-03-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-04-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-05-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-06-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-07-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-08-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-09-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-10-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-11-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-12-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-13-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-14-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-15-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-16-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-17-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-18-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-19-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-20-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-21-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-22-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-23-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-24-edges-srl-conll2012/run\"],\"score\":{\"__ndarray__\":\"p0NJbJox6j+9Z07rtVfqP1PseqgNaOo/HKZ+X1TS6j+MMJnNS+/qP0WrgUxD7Oo/GzbqltcL6z9dxYU7VkrrP4nsI+WSZOs/ndvXyIyc6z84W0n2ufLrP818ndEd/+s/Lm/Z0uZU7D8TL3K6xIvsP1nqigaL5ew/YRWK2c4J7T/aLhLiRD7tP0IvuJm0b+0/H2sgaJVw7T8VIb1lCF3tPxNyKuAXbu0/1Ekl11957T/yp2OHCXjtP1qcpWasa+0/+66CKpE47D/OCkjTxH7sPx+0+9SQuOw/QcBYKVBK7T9A2Z086WHtP54aNGcGW+0/lbI8rzh37T8PQF+mXoPtP1FcA17Qk+0/+7mdAvXM7T9HDi4SvRTuP0z8coaBR+4/2PVjVzJj7j+pYfLAnoLuP8sV6hm6fu4/zWRoVgeT7j/rLb5I8ozuP/axCNkujO4//xwAuXqa7j/UF1O/h5fuPwwD9TIfmu4/H5iM7i2T7j9eHu97FI/uP5XlmwrXkO4/DXFB5fre7T82R3GCVdrtP/ZxHFZY6u0/isgy5aoN7j8QCKf1kz3uPwoME9ztOu4/ZPhQRlFN7j9hgf95Q1XuP2r6c7iVXe4/GuE+1WBo7j/wdEmnh4zuP8FSk6WFkO4/reHvIhig7j/rLOjDTaruP7eTG2l6u+4/BgKQQj7M7j8rpCc7kcbuP1j77fHqz+4/dwajPpvT7j9+rDobZ9HuP90+iqopye4/UhgAk3bR7j8osd/uL9DuP4+pfJEmxO4/iwDrqaRw6T8CrKgDJ8vpPyWIfP148ek/etiwH3/O6j9m9LgWRvzqPy+3YkriAes/ExFHO6Xv6j8sCuXlKg3rP8fZZhpRK+s/OF7wNOVq6z8LsGv9E6XrP1O3oDFM0+s/pNTigxXK6z9+JtZlAsPrP72gAcyiy+s/6KMAT6Dl6z/h0C3D2rzrP6kduaWP6+s/5qp22xfi6z+Revg2u+nrPx3Y7gn1yes//BLRWE276z/DJEODp8vrPzr9rOWW0+s/OKTj0M9U7T+Hc48vaNHtP1pwwwHQ/u0/wmrxj0JR7j+2zdv803HuP1ILmCxAg+4/z6a8bfGb7j9hovBMZqnuP43C6SP8ru4/g1JfSnK+7j+xM0FHW9juP0a6Kji36+4/qrJL/Fv87j90IRCUSfruPxtY3gjd8O4/6hHXqq347j81+ZkZPvHuP0adVA8B8+4/7EckneL37j/SoX+TdvPuP0ofe0xf8+4/VEJbCWXy7j+y/pqJtPHuP9Yv5qwS8e4/RB64inam5D/kE4ucSPHkP2CNifRA5eQ/VM/hHaHL5T9dFh3O0gzmPzIdYcRBquY/WI4aV44a5z8RBNev21rnP35OWMM7o+c/V3zFV3zF5z9yr4JZUg7oP8nSDmTjfug/PIjvIL6D6D8RdVqXAK/oPwxmmqRNEek/aF4Pu/qT6T8R1bg2ePrpP7To+AhyDOo/V7PzVKlQ6j/bALa3I5PqP8uU4icboOo/Te07F+Tq6j9ydGiSf8HqP/4H5GEp7+o/Ia/yfEj/6D+yNzNpCxzpP1nPMVnPMek/WhfImXdk6T881z1JvHPpP11xo29niuk/enYyLbma6T97sK3p37HpP2A/NNsS0Ok/R2io9y/s6T+HwMtW1/bpP5YWcTCDI+o/BhLgnC8h6j8/OExvVTfqP+4MxCOdSeo/Xtk3mml46j/sDcK2jYjqP7V/8pJnnOo/7z7cAgqj6j/Ib9P/57LqP+YvM6Jkzeo/ou6sGerO6j/+lI1M9drqP/nCVgpjyuo/DpL7WS0r6j9Km3635DXrPx8ADkkWpuo/uGT8L9eR6z8ZCKtQ957rP2DfQLs7pes/EJ5d+UDp6z9iaBgf+EnsP/42oKxqJew/UkIFq5lp7D9L1QsJK8vsPwLH61sY1+w/mD4bfJUY7T+uVPHwSTrtP7CZY81SN+0/tytSaoVQ7T8HuM7CjUTtP8X9eIb1Mu0/P1o1p45D7T+QbcEEyFXtP7CAQse8Ve0/ANgXt09E7T99yFW4IFPtP1P0yyhPQ+0/\",\"dtype\":\"float64\",\"shape\":[192]},\"score_errn95\":{\"__ndarray__\":\"YbyXW15qhD83mxUglT6EP6TjVjSnIoQ/egk/W3Z+gz+hkn2X90+DPyGni5UxWYM/yDjWnvkigz+3V8b+XrCCP6sQ/SP1jII/tCQwnJgigj/E279c13yBP5MZxbC0cYE/6sViBDS9gD838IN551WAP96jb/mnKn8/Hlst8aiHfj8qbxpEFZl9Pz6hqemOonw/JDrU/oORfD/Z/zWnZvd8P6l5aKu4qXw/envGuChifD8An6bUVHF8P1xVcqClrnw/tfFHZpDvbz/efdJWmvluP8eWhMMOE24/HvVgdf+taz+ODjvul0RrP13RAjFaUms/uUE5MPHHaj9L7gKADpNqP3zY2gYzO2o/Wb1i+KQhaT8HXFxs5qdnP2usiuD8kWY/ugMy7vbXZT993WUhUA9lPx2EYV40J2U/FAU5yduhZD+sORxUwNZkPz3L9Yvo12Q/K7Gh7Z5rZD8A1qMTTYpkP8fHKEvidGQ/x2OT5b6uZD8FxZbPv8ZkP7vF21h/t2Q/NWaSgEXoaz9ZcqU5MP9rP6PZpqtbqWs/XEIZJPnKaj/uNZ+jiJBpP2BMDpcGo2k/3kr9uNkdaT+dUvQ8p+RoP85V7qKym2g/5I/0fXhXaD/N3PyrYk1nPyStC2aVJGc/oc0iBcejZj/eomBdBWJmP2A+xYlP12U/2WmTH9VDZT9ydYJq7mtlPwf+fg6hJGU/2x97mc0FZT/Q30HLnxBlP1O41pD/UmU/iCg0REgIZT9cLItEVBBlPxKAthfSa2U/XoZcAwvlWT9bPWy9iVJZP5NlQfwmF1k/1wH9MbuUVz8G1u7Qcz1XP1nEpmsOMlc/ZSDnr+xVVz/isiZ5oBtXP4egxcw/3FY/YDqjA+NVVj+j6P6e19ZVPzDi4QGxWlU/1mnvGzyIVT/8ShLO6ZpVP9xVbObFjVU//Us4IuxKVT/z7w+vmKRVP5cQCQ0qM1U/xEV7AE1OVT+OZxf/3DxVP3kXTERpkFU/Nx6MMCGjVT+p3MJf5YRVPyN56PwneVU/+CmZCEh/UD8hnKjZ9gpOP0NeIxzd4Uw/UVqDBdaeSj+Lgvvu4aRJPwrC/XeAGUk/JgFo5SdRSD9crpyUHeBHP+iwPIGCsEc/Lwr3kscoRz+u1YvdRD1GP8Q+t2Q4hkU/eiAqREHlRD+Q8tGpj/hEP6oFeIpFUkU/JefzlmsIRT9ubzk+tlFFP2bprwPUP0U/Qy3TCsgQRT9KF6vRNDtFPye6bh1qPEU/YfxrBV9FRT/YhRjvI01FP8QXNK3PU0U/imG10137nz96kvjPZhyfP8yWEBieiJ8/pTsu6p7Xnj+eSWPUyjSeP4o/3vicnZ0/0datB50qnT/j9Cvee+WcPxp6H94FrZw/EjSnb5ZinD+ZS7M5jeabP4XSXDXaPJs/Q52zr4rpmj+zaLb5yfKaP3RMtsbII5o/T5Iw3X9bmT/Ac3SfzKCYP/d4duaHqZg/poHpxxppmD9h+inv+vSXP7qblP7a/pc/8BgtthpGlz8kezGKqnCXPwW/sJsZ/ZY/7W0xEZqbhT8Jc1OB5Y2FP5dglwYdboU/VKW5C7cchT/QS6HKlgeFP4EAQseH64Q/xqKeaGn1hD/Le9wM386EP4hZQX5uqoQ//z0HB4F+hD8b7to5GT+EPx+Vy6HuJIQ/1RAg00EzhD8lxTI/QhuEP65+bv7A/oM/7tduyPSmgz8LN5e5xaWDP82jC/M+jYM/uc6VpH1+gz99De5zSG2DPxCoS8MDL4M/E2iWicM1gz/PPP0+6SqDP/MYEB3iHIM/NKFILzC2ZT/k1Lcy/O9jP6GBP09Q4WQ/8l/Ksms5Yz+IX9oC2ihjP7W3Vg0yGmM/lHhnMnmfYj/tf9F0kd1hP1D/HSqoJmI/uF3kgVuQYT+QyCwFtMNgP5z3hw9NjGA/hpLc09P5Xz8OPavsFF9fP4ag8vb2ZF8//8zuSkb2Xj/p+iz9vzZfP+22DrTqmV8/D9xeIdUxXz9sHOBcjM1eP0MslZLV514/MZ7JVSQqXz9pAChUcvVeP+P36luDMV8/\",\"dtype\":\"float64\",\"shape\":[192]},\"seed\":[\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\"],\"split\":[\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\"],\"stratifier\":[\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\"],\"stratum_key\":{\"__ndarray__\":\"AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/\",\"dtype\":\"float64\",\"shape\":[192]},\"tag\":[\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\"],\"task\":[\"coref-ontonotes-conll\",\"coref-ontonotes-conll\",\"coref-ontonotes-conll\",\"coref-ontonotes-conll\",\"coref-ontonotes-conll\",\"coref-ontonotes-conll\",\"coref-ontonotes-conll\",\"coref-ontonotes-conll\",\"coref-ontonotes-conll\",\"coref-ontonotes-conll\",\"coref-ontonotes-conll\",\"coref-ontonotes-conll\",\"coref-ontonotes-conll\",\"coref-ontonotes-conll\",\"coref-ontonotes-conll\",\"coref-ontonotes-conll\",\"coref-ontonotes-conll\",\"coref-ontonotes-conll\",\"coref-ontonotes-conll\",\"coref-ontonotes-conll\",\"coref-ontonotes-conll\",\"coref-ontonotes-conll\",\"coref-ontonotes-conll\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"dep-labeling-ewt\",\"dep-labeling-ewt\",\"dep-labeling-ewt\",\"dep-labeling-ewt\",\"dep-labeling-ewt\",\"dep-labeling-ewt\",\"dep-labeling-ewt\",\"dep-labeling-ewt\",\"dep-labeling-ewt\",\"dep-labeling-ewt\",\"dep-labeling-ewt\",\"dep-labeling-ewt\",\"dep-labeling-ewt\",\"dep-labeling-ewt\",\"dep-labeling-ewt\",\"dep-labeling-ewt\",\"dep-labeling-ewt\",\"dep-labeling-ewt\",\"dep-labeling-ewt\",\"dep-labeling-ewt\",\"dep-labeling-ewt\",\"dep-labeling-ewt\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"ner-ontonotes\",\"ner-ontonotes\",\"ner-ontonotes\",\"ner-ontonotes\",\"ner-ontonotes\",\"ner-ontonotes\",\"ner-ontonotes\",\"ner-ontonotes\",\"ner-ontonotes\",\"ner-ontonotes\",\"ner-ontonotes\",\"ner-ontonotes\",\"ner-ontonotes\",\"ner-ontonotes\",\"ner-ontonotes\",\"ner-ontonotes\",\"ner-ontonotes\",\"ner-ontonotes\",\"ner-ontonotes\",\"ner-ontonotes\",\"ner-ontonotes\",\"ner-ontonotes\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"nonterminal-ontonotes\",\"nonterminal-ontonotes\",\"nonterminal-ontonotes\",\"nonterminal-ontonotes\",\"nonterminal-ontonotes\",\"nonterminal-ontonotes\",\"nonterminal-ontonotes\",\"nonterminal-ontonotes\",\"nonterminal-ontonotes\",\"nonterminal-ontonotes\",\"nonterminal-ontonotes\",\"nonterminal-ontonotes\",\"nonterminal-ontonotes\",\"nonterminal-ontonotes\",\"nonterminal-ontonotes\",\"nonterminal-ontonotes\",\"nonterminal-ontonotes\",\"nonterminal-ontonotes\",\"nonterminal-ontonotes\",\"nonterminal-ontonotes\",\"nonterminal-ontonotes\",\"nonterminal-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"pos-ontonotes\",\"pos-ontonotes\",\"pos-ontonotes\",\"pos-ontonotes\",\"pos-ontonotes\",\"pos-ontonotes\",\"pos-ontonotes\",\"pos-ontonotes\",\"pos-ontonotes\",\"pos-ontonotes\",\"pos-ontonotes\",\"pos-ontonotes\",\"pos-ontonotes\",\"pos-ontonotes\",\"pos-ontonotes\",\"pos-ontonotes\",\"pos-ontonotes\",\"pos-ontonotes\",\"pos-ontonotes\",\"pos-ontonotes\",\"pos-ontonotes\",\"pos-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"rel-semeval\",\"rel-semeval\",\"rel-semeval\",\"rel-semeval\",\"rel-semeval\",\"rel-semeval\",\"rel-semeval\",\"rel-semeval\",\"rel-semeval\",\"rel-semeval\",\"rel-semeval\",\"rel-semeval\",\"rel-semeval\",\"rel-semeval\",\"rel-semeval\",\"rel-semeval\",\"rel-semeval\",\"rel-semeval\",\"rel-semeval\",\"rel-semeval\",\"rel-semeval\",\"rel-semeval\",\"rel-semeval\",\"spr1\",\"spr1\",\"spr1\",\"spr1\",\"spr1\",\"spr1\",\"spr1\",\"spr1\",\"spr1\",\"spr1\",\"spr1\",\"spr1\",\"spr1\",\"spr1\",\"spr1\",\"spr1\",\"spr1\",\"spr1\",\"spr1\",\"spr1\",\"spr1\",\"spr1\",\"spr1\",\"spr1\",\"srl-conll2012\",\"srl-conll2012\",\"srl-conll2012\",\"srl-conll2012\",\"srl-conll2012\",\"srl-conll2012\",\"srl-conll2012\",\"srl-conll2012\",\"srl-conll2012\",\"srl-conll2012\",\"srl-conll2012\",\"srl-conll2012\",\"srl-conll2012\",\"srl-conll2012\",\"srl-conll2012\",\"srl-conll2012\",\"srl-conll2012\",\"srl-conll2012\",\"srl-conll2012\",\"srl-conll2012\",\"srl-conll2012\",\"srl-conll2012\",\"srl-conll2012\",\"srl-conll2012\"],\"tn_count\":{\"__ndarray__\":\"AAAAAMAc00AAAAAAADjTQAAAAADALdNAAAAAAIA200AAAAAAQDnTQAAAAABAQNNAAAAAAEA+00AAAAAAADvTQAAAAACAR9NAAAAAAEBH00AAAAAAwE7TQAAAAABAWdNAAAAAAEBe00AAAAAAAG3TQAAAAADAfdNAAAAAAACF00AAAAAAAJTTQAAAAAAAndNAAAAAAACW00AAAAAAwJPTQAAAAACAm9NAAAAAAMCW00AAAAAAwJnTQAAAAADAltNAAAAAAE2/MkEAAAAAiL8yQQAAAADcvzJBAAAAAJ/AMkEAAAAAvsAyQQAAAADSwDJBAAAAAAjBMkEAAAAAE8EyQQAAAAA6wTJBAAAAAI7BMkEAAAAA+cEyQQAAAAA3wjJBAAAAAITCMkEAAAAAvsIyQQAAAAC5wjJBAAAAAN7CMkEAAAAAv8IyQQAAAADEwjJBAAAAAPLCMkEAAAAA3MIyQQAAAADnwjJBAAAAAMjCMkEAAAAAxsIyQQAAAADPwjJBAAAAAHRLFkEAAAAAgEsWQQAAAACISxZBAAAAAIhMFkEAAAAA0E0WQQAAAAC4TRZBAAAAAHxOFkEAAAAAxE4WQQAAAABoTxZBAAAAAHhPFkEAAAAAeFAWQQAAAADcUBZBAAAAAIBRFkEAAAAAcFEWQQAAAADwURZBAAAAAKBSFkEAAAAAoFIWQQAAAAC8UhZBAAAAANRSFkEAAAAA8FIWQQAAAADEUhZBAAAAABhTFkEAAAAAHFMWQQAAAADwUhZBAAAAgP0VXEEAAABAcBdcQQAAAIAvF1xBAAAAQI0YXEEAAABAshhcQQAAAABpGVxBAAAAgDwYXEEAAACAABhcQQAAAIBiF1xBAAAAAOEXXEEAAACAtBhcQQAAAMCbF1xBAAAAwO0ZXEEAAABAPRpcQQAAAIDmG1xBAAAAgKMaXEEAAAAAfhlcQQAAAMCQGVxBAAAAQPQZXEEAAABAHxpcQQAAAEB5G1xBAAAAANQYXEEAAADA/BlcQQAAAMA3G1xBAAAAoDH1aUEAAABgI/dpQQAAACC892lBAAAAQLX4aUEAAADAOPlpQQAAAMCG+WlBAAAAoNL5aUEAAADA//lpQQAAAEAR+mlBAAAAQFj6aUEAAAAgyPppQQAAAIAW+2lBAAAAQD37aUEAAABgSftpQQAAAGA7+2lBAAAAwEP7aUEAAAAgIvtpQQAAAMAw+2lBAAAAYDr7aUEAAADgM/tpQQAAAGAw+2lBAAAAIDL7aUEAAADAJPtpQQAAAIAb+2lBAAAAAIAf00AAAAAAQCjTQAAAAADAI9NAAAAAAIAg00AAAAAAQCbTQAAAAACAJdNAAAAAAAAl00AAAAAAwCTTQAAAAAAAI9NAAAAAAAAl00AAAAAAwCbTQAAAAAAAKNNAAAAAAMAq00AAAAAAgCjTQAAAAABAK9NAAAAAAAAs00AAAAAAQC3TQAAAAABALNNAAAAAAAAr00AAAAAAgCvTQAAAAABAKtNAAAAAAMAs00AAAAAAgC3TQAAAAADALtNAAAAAAACgx0AAAAAAgM7HQAAAAAAAyMdAAAAAAICzx0AAAAAAgLTHQAAAAACAu8dAAAAAAAD7x0AAAAAAgOzHQAAAAACA+8dAAAAAAID1x0AAAAAAgLPHQAAAAAAA7cdAAAAAAID+x0AAAAAAABLIQAAAAACAEchAAAAAAAD+x0AAAAAAACfIQAAAAACAN8hAAAAAAIAuyEAAAAAAgELIQAAAAAAAIchAAAAAAIAvyEAAAAAAgEHIQAAAAAAABMhAAAAAAOkeQUEAAAAAkyFBQQAAAICJIEFBAAAAANAiQUEAAACAsSJBQQAAAIDUIkFBAAAAAC4jQUEAAAAA/SNBQQAAAAC6I0FBAAAAAJEkQUEAAAAALSVBQQAAAAD+JUFBAAAAgFcmQUEAAAAAhyZBQQAAAACcJkFBAAAAAKYmQUEAAAAAeyZBQQAAAIAnJkFBAAAAAJomQUEAAACA4CZBQQAAAACIJkFBAAAAgKgmQUEAAACAgCZBQQAAAICeJkFB\",\"dtype\":\"float64\",\"shape\":[192]},\"total_count\":{\"__ndarray__\":\"AAAAAEC32UAAAAAAQLfZQAAAAABAt9lAAAAAAEC32UAAAAAAQLfZQAAAAABAt9lAAAAAAEC32UAAAAAAQLfZQAAAAABAt9lAAAAAAEC32UAAAAAAQLfZQAAAAABAt9lAAAAAAEC32UAAAAAAQLfZQAAAAABAt9lAAAAAAEC32UAAAAAAQLfZQAAAAABAt9lAAAAAAEC32UAAAAAAQLfZQAAAAABAt9lAAAAAAEC32UAAAAAAQLfZQAAAAABAt9lAAAAAAEwoM0EAAAAATCgzQQAAAABMKDNBAAAAAEwoM0EAAAAATCgzQQAAAABMKDNBAAAAAEwoM0EAAAAATCgzQQAAAABMKDNBAAAAAEwoM0EAAAAATCgzQQAAAABMKDNBAAAAAEwoM0EAAAAATCgzQQAAAABMKDNBAAAAAEwoM0EAAAAATCgzQQAAAABMKDNBAAAAAEwoM0EAAAAATCgzQQAAAABMKDNBAAAAAEwoM0EAAAAATCgzQQAAAABMKDNBAAAAAJiaF0EAAAAAmJoXQQAAAACYmhdBAAAAAJiaF0EAAAAAmJoXQQAAAACYmhdBAAAAAJiaF0EAAAAAmJoXQQAAAACYmhdBAAAAAJiaF0EAAAAAmJoXQQAAAACYmhdBAAAAAJiaF0EAAAAAmJoXQQAAAACYmhdBAAAAAJiaF0EAAAAAmJoXQQAAAACYmhdBAAAAAJiaF0EAAAAAmJoXQQAAAACYmhdBAAAAAJiaF0EAAAAAmJoXQQAAAACYmhdBAAAAgJkyXUEAAACAmTJdQQAAAICZMl1BAAAAgJkyXUEAAACAmTJdQQAAAICZMl1BAAAAgJkyXUEAAACAmTJdQQAAAICZMl1BAAAAgJkyXUEAAACAmTJdQQAAAICZMl1BAAAAgJkyXUEAAACAmTJdQQAAAICZMl1BAAAAgJkyXUEAAACAmTJdQQAAAICZMl1BAAAAgJkyXUEAAACAmTJdQQAAAICZMl1BAAAAgJkyXUEAAACAmTJdQQAAAICZMl1BAAAAAC6NakEAAAAALo1qQQAAAAAujWpBAAAAAC6NakEAAAAALo1qQQAAAAAujWpBAAAAAC6NakEAAAAALo1qQQAAAAAujWpBAAAAAC6NakEAAAAALo1qQQAAAAAujWpBAAAAAC6NakEAAAAALo1qQQAAAAAujWpBAAAAAC6NakEAAAAALo1qQQAAAAAujWpBAAAAAC6NakEAAAAALo1qQQAAAAAujWpBAAAAAC6NakEAAAAALo1qQQAAAAAujWpBAAAAAIAy1EAAAAAAgDLUQAAAAACAMtRAAAAAAIAy1EAAAAAAgDLUQAAAAACAMtRAAAAAAIAy1EAAAAAAgDLUQAAAAACAMtRAAAAAAIAy1EAAAAAAgDLUQAAAAACAMtRAAAAAAIAy1EAAAAAAgDLUQAAAAACAMtRAAAAAAIAy1EAAAAAAgDLUQAAAAACAMtRAAAAAAIAy1EAAAAAAgDLUQAAAAACAMtRAAAAAAIAy1EAAAAAAgDLUQAAAAACAMtRAAAAAAIDT0kAAAAAAgNPSQAAAAACA09JAAAAAAIDT0kAAAAAAgNPSQAAAAACA09JAAAAAAIDT0kAAAAAAgNPSQAAAAACA09JAAAAAAIDT0kAAAAAAgNPSQAAAAACA09JAAAAAAIDT0kAAAAAAgNPSQAAAAACA09JAAAAAAIDT0kAAAAAAgNPSQAAAAACA09JAAAAAAIDT0kAAAAAAgNPSQAAAAACA09JAAAAAAIDT0kAAAAAAgNPSQAAAAACA09JAAAAAAIjOQUEAAAAAiM5BQQAAAACIzkFBAAAAAIjOQUEAAAAAiM5BQQAAAACIzkFBAAAAAIjOQUEAAAAAiM5BQQAAAACIzkFBAAAAAIjOQUEAAAAAiM5BQQAAAACIzkFBAAAAAIjOQUEAAAAAiM5BQQAAAACIzkFBAAAAAIjOQUEAAAAAiM5BQQAAAACIzkFBAAAAAIjOQUEAAAAAiM5BQQAAAACIzkFBAAAAAIjOQUEAAAAAiM5BQQAAAACIzkFB\",\"dtype\":\"float64\",\"shape\":[192]},\"tp_count\":{\"__ndarray__\":\"AAAAAABNskAAAAAAAC6yQAAAAAAAXrJAAAAAAADEskAAAAAAAN+yQAAAAAAAx7JAAAAAAADzskAAAAAAAEmzQAAAAAAARLNAAAAAAACKs0AAAAAAAN+zQAAAAAAAzrNAAAAAAAArtEAAAAAAAEK0QAAAAAAAf7RAAAAAAACWtEAAAAAAAKi0QAAAAAAAyrRAAAAAAADjtEAAAAAAANG0QAAAAAAAzbRAAAAAAADstEAAAAAAAOC0QAAAAAAA2rRAAAAAAEC01EAAAAAAQAXVQAAAAACAQdVAAAAAAEDf1UAAAAAAQPnVQAAAAACA69VAAAAAAAAH1kAAAAAAgBXWQAAAAAAAJNZAAAAAAMBh1kAAAAAAwK/WQAAAAACA6tZAAAAAAAAB10AAAAAAQCHXQAAAAADAHNdAAAAAAMAx10AAAAAAADDXQAAAAADALddAAAAAAAA410AAAAAAwDjXQAAAAAAAOtdAAAAAAAA310AAAAAAgDHXQAAAAAAAMtdAAAAAAEBV0kAAAAAAQE/SQAAAAABAYdJAAAAAAAB80kAAAAAAgKHSQAAAAADAn9JAAAAAAECq0kAAAAAAgK/SQAAAAAAAsNJAAAAAAMC70kAAAAAAwNfSQAAAAADA1tJAAAAAAMDf0kAAAAAAwOzSQAAAAADA+dJAAAAAAIAD00AAAAAAwPzSQAAAAABABtNAAAAAAEAJ00AAAAAAAAXTQAAAAADA/dJAAAAAAMAC00AAAAAAAAHTQAAAAABA9dJAAAAAALB4B0EAAAAASOUHQQAAAACAJghBAAAAAAhpCUEAAAAAsLAJQQAAAABAqQlBAAAAAKCmCUEAAAAA0NwJQQAAAAB4HQpBAAAAAIh8CkEAAAAAYMsKQQAAAACgNQtBAAAAALjsCkEAAAAAANkKQQAAAADwvgpBAAAAAHgKC0EAAAAAyOAKQQAAAABALwtBAAAAAFAVC0EAAAAAUB4LQQAAAACQxgpBAAAAAGDuCkEAAAAA+O0KQQAAAABI3QpBAAAAAMgSEEEAAAAAWFwQQQAAAABkehBBAAAAAGy0EEEAAAAAvMcQQQAAAAA00RBBAAAAAJjiEEEAAAAAqOsQQQAAAACQ7xBBAAAAAMj3EEEAAAAAYAYRQQAAAADkERFBAAAAACgfEUEAAAAAhBsRQQAAAAAUExFBAAAAAHQaEUEAAAAAcBYRQQAAAACcFhFBAAAAALQaEUEAAAAAvBYRQQAAAAAMFxFBAAAAAMwVEUEAAAAAoBYRQQAAAAAIFxFBAAAAAABggEAAAAAAADCAQAAAAAAAaIBAAAAAAACwgUAAAAAAAKCBQAAAAAAAcIJAAAAAAAAIg0AAAAAAAGCDQAAAAAAA4INAAAAAAADog0AAAAAAACiEQAAAAAAAqIRAAAAAAAB4hEAAAAAAAOCEQAAAAAAAMIVAAAAAAADYhUAAAAAAAFCGQAAAAAAAgIZAAAAAAAAAh0AAAAAAAFiHQAAAAAAAiIdAAAAAAADAh0AAAAAAAHCHQAAAAAAAmIdAAAAAAAD7sUAAAAAAAOGxQAAAAAAAA7JAAAAAAABaskAAAAAAAGuyQAAAAAAAfbJAAAAAAAA8skAAAAAAAGuyQAAAAAAAe7JAAAAAAAClskAAAAAAAAyzQAAAAAAA9LJAAAAAAADZskAAAAAAANmyQAAAAAAA8LJAAAAAAABFs0AAAAAAAB+zQAAAAAAAILNAAAAAAAA1s0AAAAAAACyzQAAAAAAAfbNAAAAAAABqs0AAAAAAAF+zQAAAAAAAo7NAAAAAAMBe7kAAAAAAIPvvQAAAAADgCO9AAAAAAIA+8EAAAAAAAE/wQAAAAAAwUvBAAAAAAMCQ8EAAAAAAIOPwQAAAAADAwvBAAAAAAFD28EAAAAAAQFDxQAAAAADgR/FAAAAAAICG8UAAAAAA4KbxQAAAAABgofFAAAAAAGC88UAAAAAAkLPxQAAAAADAqPFAAAAAADCv8UAAAAAAELzxQAAAAABgxfFAAAAAAICu8UAAAAAAQMPxQAAAAABwrvFA\",\"dtype\":\"float64\",\"shape\":[192]},\"true_pos_count\":{\"__ndarray__\":\"AAAAAACutkAAAAAAAK62QAAAAAAArrZAAAAAAACutkAAAAAAAK62QAAAAAAArrZAAAAAAACutkAAAAAAAK62QAAAAAAArrZAAAAAAACutkAAAAAAAK62QAAAAAAArrZAAAAAAACutkAAAAAAAK62QAAAAAAArrZAAAAAAACutkAAAAAAAK62QAAAAAAArrZAAAAAAACutkAAAAAAAK62QAAAAAAArrZAAAAAAACutkAAAAAAAK62QAAAAAAArrZAAAAAAICF2EAAAAAAgIXYQAAAAACAhdhAAAAAAICF2EAAAAAAgIXYQAAAAACAhdhAAAAAAICF2EAAAAAAgIXYQAAAAACAhdhAAAAAAICF2EAAAAAAgIXYQAAAAACAhdhAAAAAAICF2EAAAAAAgIXYQAAAAACAhdhAAAAAAICF2EAAAAAAgIXYQAAAAACAhdhAAAAAAICF2EAAAAAAgIXYQAAAAACAhdhAAAAAAICF2EAAAAAAgIXYQAAAAACAhdhAAAAAAIDg00AAAAAAgODTQAAAAACA4NNAAAAAAIDg00AAAAAAgODTQAAAAACA4NNAAAAAAIDg00AAAAAAgODTQAAAAACA4NNAAAAAAIDg00AAAAAAgODTQAAAAACA4NNAAAAAAIDg00AAAAAAgODTQAAAAACA4NNAAAAAAIDg00AAAAAAgODTQAAAAACA4NNAAAAAAIDg00AAAAAAgODTQAAAAACA4NNAAAAAAIDg00AAAAAAgODTQAAAAACA4NNAAAAAAOgkD0EAAAAA6CQPQQAAAADoJA9BAAAAAOgkD0EAAAAA6CQPQQAAAADoJA9BAAAAAOgkD0EAAAAA6CQPQQAAAADoJA9BAAAAAOgkD0EAAAAA6CQPQQAAAADoJA9BAAAAAOgkD0EAAAAA6CQPQQAAAADoJA9BAAAAAOgkD0EAAAAA6CQPQQAAAADoJA9BAAAAAOgkD0EAAAAA6CQPQQAAAADoJA9BAAAAAOgkD0EAAAAA6CQPQQAAAADoJA9BAAAAAHSzEUEAAAAAdLMRQQAAAAB0sxFBAAAAAHSzEUEAAAAAdLMRQQAAAAB0sxFBAAAAAHSzEUEAAAAAdLMRQQAAAAB0sxFBAAAAAHSzEUEAAAAAdLMRQQAAAAB0sxFBAAAAAHSzEUEAAAAAdLMRQQAAAAB0sxFBAAAAAHSzEUEAAAAAdLMRQQAAAAB0sxFBAAAAAHSzEUEAAAAAdLMRQQAAAAB0sxFBAAAAAHSzEUEAAAAAdLMRQQAAAAB0sxFBAAAAAAAIjkAAAAAAAAiOQAAAAAAACI5AAAAAAAAIjkAAAAAAAAiOQAAAAAAACI5AAAAAAAAIjkAAAAAAAAiOQAAAAAAACI5AAAAAAAAIjkAAAAAAAAiOQAAAAAAACI5AAAAAAAAIjkAAAAAAAAiOQAAAAAAACI5AAAAAAAAIjkAAAAAAAAiOQAAAAAAACI5AAAAAAAAIjkAAAAAAAAiOQAAAAAAACI5AAAAAAAAIjkAAAAAAAAiOQAAAAAAACI5AAAAAAABGt0AAAAAAAEa3QAAAAAAARrdAAAAAAABGt0AAAAAAAEa3QAAAAAAARrdAAAAAAABGt0AAAAAAAEa3QAAAAAAARrdAAAAAAABGt0AAAAAAAEa3QAAAAAAARrdAAAAAAABGt0AAAAAAAEa3QAAAAAAARrdAAAAAAABGt0AAAAAAAEa3QAAAAAAARrdAAAAAAABGt0AAAAAAAEa3QAAAAAAARrdAAAAAAABGt0AAAAAAAEa3QAAAAAAARrdAAAAAAKDF80AAAAAAoMXzQAAAAACgxfNAAAAAAKDF80AAAAAAoMXzQAAAAACgxfNAAAAAAKDF80AAAAAAoMXzQAAAAACgxfNAAAAAAKDF80AAAAAAoMXzQAAAAACgxfNAAAAAAKDF80AAAAAAoMXzQAAAAACgxfNAAAAAAKDF80AAAAAAoMXzQAAAAACgxfNAAAAAAKDF80AAAAAAoMXzQAAAAACgxfNAAAAAAKDF80AAAAAAoMXzQAAAAACgxfNA\",\"dtype\":\"float64\",\"shape\":[192]}},\"selected\":{\"id\":\"3382\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"3383\",\"type\":\"UnionRenderers\"}},\"id\":\"3248\",\"type\":\"ColumnDataSource\"},{\"attributes\":{},\"id\":\"3374\",\"type\":\"Selection\"},{\"attributes\":{\"fill_color\":{\"value\":\"#3182bd\"},\"height\":{\"field\":\"_bar_height\",\"units\":\"data\"},\"line_color\":{\"value\":\"#3182bd\"},\"width\":{\"units\":\"data\",\"value\":0.9},\"x\":{\"field\":\"layer_num\"},\"y\":{\"field\":\"_bar_center\",\"transform\":{\"id\":\"3233\",\"type\":\"Dodge\"}}},\"id\":\"3236\",\"type\":\"Rect\"},{\"attributes\":{},\"id\":\"3373\",\"type\":\"BasicTickFormatter\"},{\"attributes\":{\"source\":{\"id\":\"3227\",\"type\":\"ColumnDataSource\"}},\"id\":\"3232\",\"type\":\"CDSView\"},{\"attributes\":{\"plot\":{\"id\":\"3199\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"ticker\":{\"id\":\"3261\",\"type\":\"FixedTicker\"}},\"id\":\"3211\",\"type\":\"Grid\"},{\"attributes\":{},\"id\":\"3371\",\"type\":\"CategoricalTickFormatter\"},{\"attributes\":{\"ticks\":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24]},\"id\":\"3261\",\"type\":\"FixedTicker\"},{\"attributes\":{\"callback\":null,\"data\":{\"_bar_center\":[\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\"],\"_bar_height\":[0.04494346976280213,0.04006913993507624,0.09287066906690598,0.0376878110691905,0.12816421128809452,0.09434745647013187,0.09976273588836193,0.06169388685375452,0.1017415925860405],\"_display_name\":[\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\"],\"_formatted_entropy\":[\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\"],\"_formatted_kl_unif\":[\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\"],\"checkpoint\":[\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\"],\"display_col\":[\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\"],\"exp_name\":[\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\"],\"exp_type\":[\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\"],\"gamma\":{\"__ndarray__\":\"AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/\",\"dtype\":\"float64\",\"shape\":[9]},\"index\":[0,1,2,3,4,5,6,7,8],\"label\":[\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\"],\"layer_num\":[0,0,0,0,0,0,0,0,0],\"layer_weight\":[0.016645729541778564,0.014840422198176384,0.034396544098854065,0.01395844854414463,0.04746822640299797,0.03494350239634514,0.03694916144013405,0.022849587723612785,0.03768207132816315],\"run\":[\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\"],\"scalar_set\":[\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\"],\"tag\":[\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\"],\"task\":[\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\"],\"weight_entropy\":[4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481],\"weight_exp_layer\":{\"__ndarray__\":\"AABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipA\",\"dtype\":\"float64\",\"shape\":[9]},\"weight_exp_layer_oneplus\":{\"__ndarray__\":\"SG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytA\",\"dtype\":\"float64\",\"shape\":[9]},\"weight_kl_unif\":{\"__ndarray__\":\"w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/\",\"dtype\":\"float64\",\"shape\":[9]}},\"selected\":{\"id\":\"3386\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"3387\",\"type\":\"UnionRenderers\"}},\"id\":\"3264\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"plot\":null,\"text\":\"\"},\"id\":\"3370\",\"type\":\"Title\"},{\"attributes\":{\"data_source\":{\"id\":\"3234\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"3236\",\"type\":\"Rect\"},\"hover_glyph\":{\"id\":\"3238\",\"type\":\"Rect\"},\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"3237\",\"type\":\"Rect\"},\"selection_glyph\":null,\"view\":{\"id\":\"3240\",\"type\":\"CDSView\"}},\"id\":\"3239\",\"type\":\"GlyphRenderer\"},{\"attributes\":{},\"id\":\"3213\",\"type\":\"CategoricalTicker\"},{\"attributes\":{},\"id\":\"3389\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"formatter\":{\"id\":\"3371\",\"type\":\"CategoricalTickFormatter\"},\"major_label_orientation\":\"vertical\",\"major_label_text_font_size\":{\"value\":\"13pt\"},\"plot\":{\"id\":\"3199\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"ticker\":{\"id\":\"3213\",\"type\":\"CategoricalTicker\"}},\"id\":\"3212\",\"type\":\"CategoricalAxis\"},{\"attributes\":{\"source\":{\"id\":\"3234\",\"type\":\"ColumnDataSource\"}},\"id\":\"3240\",\"type\":\"CDSView\"},{\"attributes\":{\"formatter\":{\"id\":\"3373\",\"type\":\"BasicTickFormatter\"},\"major_label_text_font_size\":{\"value\":\"13pt\"},\"plot\":{\"id\":\"3199\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"ticker\":{\"id\":\"3263\",\"type\":\"FixedTicker\"}},\"id\":\"3207\",\"type\":\"LinearAxis\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"height\":{\"value\":1.0},\"left\":{\"value\":-0.5},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"right\":{\"value\":24.5},\"y\":{\"field\":\"_display_name\"}},\"id\":\"3224\",\"type\":\"HBar\"},{\"attributes\":{},\"id\":\"3388\",\"type\":\"Selection\"},{\"attributes\":{\"fill_color\":{\"value\":\"firebrick\"},\"height\":{\"field\":\"_bar_height\",\"units\":\"data\"},\"line_color\":{\"value\":\"#1f77b4\"},\"width\":{\"units\":\"data\",\"value\":0.9},\"x\":{\"field\":\"layer_num\"},\"y\":{\"field\":\"_bar_center\",\"transform\":{\"id\":\"3233\",\"type\":\"Dodge\"}}},\"id\":\"3238\",\"type\":\"Rect\"},{\"attributes\":{\"data_source\":{\"id\":\"3241\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"3243\",\"type\":\"Rect\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"3244\",\"type\":\"Rect\"},\"selection_glyph\":null,\"view\":{\"id\":\"3246\",\"type\":\"CDSView\"}},\"id\":\"3245\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.0},\"fill_color\":{\"value\":\"#1f77b4\"},\"height\":{\"units\":\"data\",\"value\":0.5},\"line_alpha\":{\"value\":0.0},\"line_color\":{\"value\":\"#1f77b4\"},\"width\":{\"units\":\"data\",\"value\":0.9},\"x\":{\"field\":\"layer_num\"},\"y\":{\"field\":\"_bar_center\",\"transform\":{\"id\":\"3233\",\"type\":\"Dodge\"}}},\"id\":\"3243\",\"type\":\"Rect\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.7},\"fill_color\":{\"value\":\"firebrick\"},\"height\":{\"field\":\"_bar_height\",\"units\":\"data\"},\"line_color\":{\"value\":\"#1f77b4\"},\"line_width\":{\"value\":1.5},\"width\":{\"units\":\"data\",\"value\":0.9},\"x\":{\"field\":\"layer_num\"},\"y\":{\"field\":\"_bar_center\",\"transform\":{\"id\":\"3247\",\"type\":\"Dodge\"}}},\"id\":\"3252\",\"type\":\"Rect\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"height\":{\"units\":\"data\",\"value\":0.5},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"width\":{\"units\":\"data\",\"value\":0.9},\"x\":{\"field\":\"layer_num\"},\"y\":{\"field\":\"_bar_center\",\"transform\":{\"id\":\"3247\",\"type\":\"Dodge\"}}},\"id\":\"3258\",\"type\":\"Rect\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.0},\"fill_color\":{\"value\":\"#1f77b4\"},\"height\":{\"units\":\"data\",\"value\":0.5},\"line_alpha\":{\"value\":0.0},\"line_color\":{\"value\":\"#1f77b4\"},\"width\":{\"units\":\"data\",\"value\":0.9},\"x\":{\"field\":\"layer_num\"},\"y\":{\"field\":\"_bar_center\",\"transform\":{\"id\":\"3247\",\"type\":\"Dodge\"}}},\"id\":\"3257\",\"type\":\"Rect\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.4},\"fill_color\":{\"value\":\"#f2f2f2\"},\"height\":{\"value\":1.0},\"left\":{\"value\":-0.5},\"line_alpha\":{\"value\":0.0},\"line_color\":{\"value\":\"#1f77b4\"},\"right\":{\"value\":24.5},\"y\":{\"field\":\"_display_name\"}},\"id\":\"3223\",\"type\":\"HBar\"},{\"attributes\":{},\"id\":\"3387\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"ticks\":[0,2,4,6,8,10,12,14,16,18,20,22,24]},\"id\":\"3263\",\"type\":\"FixedTicker\"},{\"attributes\":{\"callback\":null,\"factor_padding\":0.1,\"factors\":[\"Relations\",\"SPR\",\"Coref.\",\"SRL\",\"Entities\",\"Deps.\",\"Consts.\",\"POS\"]},\"id\":\"3198\",\"type\":\"FactorRange\"},{\"attributes\":{\"source\":{\"id\":\"3241\",\"type\":\"ColumnDataSource\"}},\"id\":\"3246\",\"type\":\"CDSView\"},{\"attributes\":{\"callback\":null,\"data\":{\"_bar_center\":[[\"Coref.\",-0.33901404143352976],[\"Coref.\",-0.446044265972713],[\"Coref.\",-0.4768604307729952],[\"Coref.\",-0.349525558451067],[\"Coref.\",-0.45898692471674774],[\"Coref.\",-0.5042943777232388],[\"Coref.\",-0.455287325332745],[\"Coref.\",-0.411515278184139],[\"Coref.\",-0.46285173750164527],[\"Coref.\",-0.42074447361521033],[\"Coref.\",-0.37798436766717003],[\"Coref.\",-0.4824573791926188],[\"Coref.\",-0.3785389022665467],[\"Coref.\",-0.42231552517488213],[\"Coref.\",-0.37289017134084423],[\"Coref.\",-0.4486531022671646],[\"Coref.\",-0.4257216273924921],[\"Coref.\",-0.430004011498989],[\"Coref.\",-0.49875678241786225],[\"Coref.\",-0.5276814122003841],[\"Coref.\",-0.47584433022688954],[\"Coref.\",-0.48402730887671264],[\"Coref.\",-0.5018934399482096],[\"Coref.\",-0.5175054552404181],[\"Deps.\",-0.15535020398162452],[\"Deps.\",-0.38428250376104167],[\"Deps.\",-0.4047307119398233],[\"Deps.\",-0.25975736407552574],[\"Deps.\",-0.46110204834685437],[\"Deps.\",-0.511350747086902],[\"Deps.\",-0.45352222160719396],[\"Deps.\",-0.4799749446492181],[\"Deps.\",-0.4728940042921681],[\"Deps.\",-0.4058080754182927],[\"Deps.\",-0.3816788121899807],[\"Deps.\",-0.4163178294914107],[\"Deps.\",-0.45435585059051226],[\"Deps.\",-0.44820326706379154],[\"Deps.\",-0.5064172948843114],[\"Deps.\",-0.4665358084766775],[\"Deps.\",-0.5100259102460774],[\"Deps.\",-0.5012581700242449],[\"Deps.\",-0.47643470567042245],[\"Deps.\",-0.5048613661154845],[\"Deps.\",-0.4957281358071249],[\"Deps.\",-0.5114439259885932],[\"Deps.\",-0.5067568946377005],[\"Deps.\",-0.4970990208708064],[\"Entities\",0.0],[\"Entities\",-0.513352993296959],[\"Entities\",-0.45398240786314914],[\"Entities\",-0.3984797211650951],[\"Entities\",-0.3623000265043117],[\"Entities\",-0.5076134742862792],[\"Entities\",-0.44715007418158437],[\"Entities\",-0.4771617602083911],[\"Entities\",-0.47608403699226265],[\"Entities\",-0.46897889679379323],[\"Entities\",-0.3960967010884767],[\"Entities\",-0.4885257724075292],[\"Entities\",-0.4552434783007919],[\"Entities\",-0.4706566887178612],[\"Entities\",-0.4506387386909693],[\"Entities\",-0.4518150528636334],[\"Entities\",-0.5163130279572037],[\"Entities\",-0.47312601139594035],[\"Entities\",-0.4893989751246502],[\"Entities\",-0.5063336345716116],[\"Entities\",-0.523682871717514],[\"Entities\",-0.47614321781526586],[\"Entities\",-0.5036677664611354],[\"Entities\",-0.5345937972945325],[\"Consts.\",0.0],[\"Consts.\",-0.3910621028560085],[\"Consts.\",-0.4538773523447979],[\"Consts.\",-0.23397349936351564],[\"Consts.\",-0.4449021225939842],[\"Consts.\",-0.4932477242812544],[\"Consts.\",-0.5219518560912718],[\"Consts.\",-0.46446696372136126],[\"Consts.\",-0.46371198033184524],[\"Consts.\",-0.423476377463428],[\"Consts.\",-0.4299708940841526],[\"Consts.\",-0.44436975998618633],[\"Consts.\",-0.5110898271055051],[\"Consts.\",-0.5085150777057504],[\"Consts.\",-0.4896168840869088],[\"Consts.\",-0.46871763034956826],[\"Consts.\",-0.5490728892947644],[\"Consts.\",-0.44378345405096703],[\"Consts.\",-0.5113955857757364],[\"Consts.\",-0.49080677516510723],[\"Consts.\",-0.5382438055653194],[\"Consts.\",-0.517638771191431],[\"Consts.\",-0.4803184557172699],[\"Consts.\",-0.49044918351332795],[\"POS\",0.0],[\"POS\",-0.2531556499070403],[\"POS\",-0.4100432150334006],[\"POS\",-0.3366571079776205],[\"POS\",-0.4354764958906403],[\"POS\",-0.4654828795727711],[\"POS\",-0.45107966860845283],[\"POS\",-0.47333985069589174],[\"POS\",-0.4889341328321864],[\"POS\",-0.46936790586023924],[\"POS\",-0.44866724303759253],[\"POS\",-0.46164593910415286],[\"POS\",-0.46702632790348986],[\"POS\",-0.5041049130460499],[\"POS\",-0.5186709460804375],[\"POS\",-0.48451691063275476],[\"POS\",-0.5147313083731214],[\"POS\",-0.4965102318777035],[\"POS\",-0.4903292855078592],[\"POS\",-0.5087608833680461],[\"POS\",-0.5001805209432605],[\"POS\",-0.5019363924931132],[\"POS\",-0.5013656364891583],[\"POS\",-0.501252354593772],[\"Relations\",-0.2810097744404242],[\"Relations\",-0.4473966156048882],[\"Relations\",-0.5084577691357417],[\"Relations\",-0.3380325112562319],[\"Relations\",-0.4541647411047742],[\"Relations\",-0.3893148814828261],[\"Relations\",-0.421047074206068],[\"Relations\",-0.45479191418941034],[\"Relations\",-0.4491157410790485],[\"Relations\",-0.4759186083501203],[\"Relations\",-0.44879212371195404],[\"Relations\",-0.42085915537429197],[\"Relations\",-0.4965869965709158],[\"Relations\",-0.4695859343912038],[\"Relations\",-0.43088872254097815],[\"Relations\",-0.40812695338126204],[\"Relations\",-0.4279434396207782],[\"Relations\",-0.4873620100926022],[\"Relations\",-0.4520400433127205],[\"Relations\",-0.4532621276226876],[\"Relations\",-0.4908838382117171],[\"Relations\",-0.44742173276179603],[\"Relations\",-0.5291015616010672],[\"Relations\",-0.4678961458829124],[\"SPR\",-0.4021549339653747],[\"SPR\",-0.42428927439112135],[\"SPR\",-0.4427049771501718],[\"SPR\",-0.366651411837394],[\"SPR\",-0.4598083461104998],[\"SPR\",-0.44032748280457656],[\"SPR\",-0.4570408511567553],[\"SPR\",-0.43905652137373347],[\"SPR\",-0.4205045115629539],[\"SPR\",-0.4259943392631838],[\"SPR\",-0.47195554585164196],[\"SPR\",-0.38240876464951784],[\"SPR\",-0.5061247685112321],[\"SPR\",-0.4416989537999864],[\"SPR\",-0.4518793063115939],[\"SPR\",-0.37680814750125236],[\"SPR\",-0.4575109014039892],[\"SPR\",-0.44774504449761543],[\"SPR\",-0.4825359765148968],[\"SPR\",-0.458231612667788],[\"SPR\",-0.4302766672319035],[\"SPR\",-0.49599513596737715],[\"SPR\",-0.4682965955490598],[\"SPR\",-0.5436214386873615],[\"SRL\",-0.4402286837439977],[\"SRL\",-0.07547103804723737],[\"SRL\",-0.7288950954687352],[\"SRL\",-0.12475370708006245],[\"SRL\",-0.479107911966435],[\"SRL\",-0.49002486309517623],[\"SRL\",-0.3917327298022487],[\"SRL\",-0.3460593810431991],[\"SRL\",-0.5581802448666476],[\"SRL\",-0.39147271907243153],[\"SRL\",-0.34470216310226187],[\"SRL\",-0.48101564365984606],[\"SRL\",-0.39576240087569664],[\"SRL\",-0.4463523946894639],[\"SRL\",-0.5047203356488055],[\"SRL\",-0.4598927848536645],[\"SRL\",-0.5190481169197733],[\"SRL\",-0.5280051592984751],[\"SRL\",-0.47358075616478074],[\"SRL\",-0.4709927682280303],[\"SRL\",-0.5000697709101073],[\"SRL\",-0.5277366245838504],[\"SRL\",-0.4764170889764226],[\"SRL\",-0.525178457570553]],\"_bar_height\":{\"__ndarray__\":\"7T+UGTCb1D/mYSgCFqC7PyRHSzTmsac/chOrGr9C0z+jkxlyqv+0P3k2DD77loE/eDnTZpTktj9XEGVK76bGP3k7EdkYBbM/dZXZFRdKxD9HY3ieajzPP/iFnVqx9qE/e16AEhMYzz+W48c2IePDP62ti4YiRdA/k/QG/SNKuj+4OyZN6APDP2uJdtFB68E/K6Datm5eZD/JVG4ghFisPzsCwY5DvKg/R7cDKCVboD/RU+OpqQVvP3loCTfz7KE/JTWeBL4O5j863OttqZ/NPwMbiGyRY8g//0EzTEXA3j/GmnasbuqzPzvyL3wPP5c/OCxgdO/Ltz/CK1S3coGkP4HUXJSswas/6y+gQ/YcyD9aYhEgTErOP1C6l9kxbMU/iVrvgatetz+uVgD0GYW6P72vgnoFSYo/Pwhc8DcisT/qzfTkdoiUP64X2MYlnWQ/ZFbdIYAhqD+Pn60Hg+mDP6GJBdBff4E/FO7evulvlz9r8dwXHq2LP997j0/Lw3c/AAAAAAAA8D+p+Bxs0FibPyJxiSqej7c/KAp6pTv9yT9oemkZJ6DRP9CZGHFOL48/3+T4PSUPuz//PQNU6GKnPxnf4Rttfag/nacG//7Drz9ZgcUWaJnKP9hbDcLMf5c/JC32qVPqtj8ypkBJLAyuPwvwBRbhRbk/+Wk4iLKruD/EuEzGXLSgP4aIq9jahKs/Z1Emef21lT8RI5kVTPGJP+wiAp5SQKg/8rwVjeltqD8mh/8f3Qt+P1iHDDhHtrE/AAAAAAAA8D/WSIehWuPLP5lrkT5jnbc/8JcGBJQG4T++YRP7yTW8P4JdKzZGqIs/pXn+H4x6pj96GX3ZYjGyP1wzbONXlLI/pYAqWA2Xwz80O61vbe3BP9FQDhuRe7w/DzrkZUO2lj8sHCdiWnCRPyzrNzq+Q5U/0hIuJT4EsD/QUEjtFCC5Pyi7sERqyLw/Yu3NoZFWlz8cyhXA5dOSPznyWiyxlLM/jqKi5eUPoj/KzB0UZiekPyzOruNgj5M/AAAAAAAA8D9sAm19mJjfPxEffGloB8c/PJWifWvo1D/uF/nDnITAP1Qqxl46rLE/nlLf7hUMuT/2cXhVzEyrP1J8s4yzqZY/HC8nCgVerz/U7ruASUi6P1PTbroko7M/AiyR1uzhsD+MQpI0UNCAP0IUNPt5HqM/1HLJE5m1nz+yzoS9ciuePxKglv6Slnw/1hXIUz3Okz9iDGbcOfGRP5sPWBhHqTc/426Hm9G5bz+pQ8kD5V9mPzTefIHBhGQ/cwV2KN8H3D+Nl0Wv1O66P+VXro5OUpE/ybmVxVm71D8m2eoTuHe3P7dlLyTcVcw/J101SkI2xD8ceiSkgyW3P6Cz5GeADbo/UUhQ1sqoqD/J1+gz6ze6P9D6cQuTQsQ/flt9Q5b1ez8fQYNk3SSvP9yleNRGscE/SoKc8v2Exz9wf0p6THLCP2kyt0ry4Zk/IZj6GjWOuD9Cu7DCBu63P/A794V+q5I/O3CJ5Inruj+BQFu9zMytPw9TBJfqb7A/wZSxzl8MyT/7UXIyx2HDP8gnuvLFVb0/MCaQCJER0T+hGw4eAJS0PxEQpmtljb4/0wOx1r3+tT92ZTXP+zO/P8dDBPvQWcQ/DWCV9Ajywj+LAJt1r7esPzxmII51Gs4/R5M4B0kWiT9m14B9otm9P2wZTotGo7g/j6OdUYCJzz/PEdCRIcG1Px6U31kpwbo/EX/mxhbioT8UcDKDqmK1P0rRAWpj2cE/2324gGdngD/MyZO6bTuwP8gkIpmMVbY/AecdkViavj81r/KFeyvrP9FioDpvTN0/21MCBwkE6D/CsmVLvGSlPw8XPDbYbZQ/Wf65YGe3yz/BBPmBU7TTP8t38xHNyb0/KsZOonHIyz8Mw06tzODTP4Fed5aicKM//Z9At1Cvyj87i6Lssne7PyTgzXOhVYM/GjjG0u6ItD8pHOJ8WYGjPwGSOW1iraw/6n0HcaUNqz8UfztfErStP60Yxhs/SiI/9830Xf1mrD+061xeHiaoP54mUa9hyKk/\",\"dtype\":\"float64\",\"shape\":[192]},\"_display_name\":[\"Coref.\",\"Coref.\",\"Coref.\",\"Coref.\",\"Coref.\",\"Coref.\",\"Coref.\",\"Coref.\",\"Coref.\",\"Coref.\",\"Coref.\",\"Coref.\",\"Coref.\",\"Coref.\",\"Coref.\",\"Coref.\",\"Coref.\",\"Coref.\",\"Coref.\",\"Coref.\",\"Coref.\",\"Coref.\",\"Coref.\",\"Coref.\",\"Deps.\",\"Deps.\",\"Deps.\",\"Deps.\",\"Deps.\",\"Deps.\",\"Deps.\",\"Deps.\",\"Deps.\",\"Deps.\",\"Deps.\",\"Deps.\",\"Deps.\",\"Deps.\",\"Deps.\",\"Deps.\",\"Deps.\",\"Deps.\",\"Deps.\",\"Deps.\",\"Deps.\",\"Deps.\",\"Deps.\",\"Deps.\",\"Entities\",\"Entities\",\"Entities\",\"Entities\",\"Entities\",\"Entities\",\"Entities\",\"Entities\",\"Entities\",\"Entities\",\"Entities\",\"Entities\",\"Entities\",\"Entities\",\"Entities\",\"Entities\",\"Entities\",\"Entities\",\"Entities\",\"Entities\",\"Entities\",\"Entities\",\"Entities\",\"Entities\",\"Consts.\",\"Consts.\",\"Consts.\",\"Consts.\",\"Consts.\",\"Consts.\",\"Consts.\",\"Consts.\",\"Consts.\",\"Consts.\",\"Consts.\",\"Consts.\",\"Consts.\",\"Consts.\",\"Consts.\",\"Consts.\",\"Consts.\",\"Consts.\",\"Consts.\",\"Consts.\",\"Consts.\",\"Consts.\",\"Consts.\",\"Consts.\",\"POS\",\"POS\",\"POS\",\"POS\",\"POS\",\"POS\",\"POS\",\"POS\",\"POS\",\"POS\",\"POS\",\"POS\",\"POS\",\"POS\",\"POS\",\"POS\",\"POS\",\"POS\",\"POS\",\"POS\",\"POS\",\"POS\",\"POS\",\"POS\",\"Relations\",\"Relations\",\"Relations\",\"Relations\",\"Relations\",\"Relations\",\"Relations\",\"Relations\",\"Relations\",\"Relations\",\"Relations\",\"Relations\",\"Relations\",\"Relations\",\"Relations\",\"Relations\",\"Relations\",\"Relations\",\"Relations\",\"Relations\",\"Relations\",\"Relations\",\"Relations\",\"Relations\",\"SPR\",\"SPR\",\"SPR\",\"SPR\",\"SPR\",\"SPR\",\"SPR\",\"SPR\",\"SPR\",\"SPR\",\"SPR\",\"SPR\",\"SPR\",\"SPR\",\"SPR\",\"SPR\",\"SPR\",\"SPR\",\"SPR\",\"SPR\",\"SPR\",\"SPR\",\"SPR\",\"SPR\",\"SRL\",\"SRL\",\"SRL\",\"SRL\",\"SRL\",\"SRL\",\"SRL\",\"SRL\",\"SRL\",\"SRL\",\"SRL\",\"SRL\",\"SRL\",\"SRL\",\"SRL\",\"SRL\",\"SRL\",\"SRL\",\"SRL\",\"SRL\",\"SRL\",\"SRL\",\"SRL\",\"SRL\"],\"_fill_color\":[\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#fd8d3c\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#fd8d3c\",\"#756bb1\",\"#756bb1\",\"#fd8d3c\",\"#fd8d3c\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#fd8d3c\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#fd8d3c\",\"#756bb1\",\"#fd8d3c\",\"#fd8d3c\",\"#756bb1\",\"#fd8d3c\",\"#756bb1\",\"#fd8d3c\",\"#fd8d3c\",\"#756bb1\",\"#756bb1\",\"#fd8d3c\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#fd8d3c\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#fd8d3c\",\"#756bb1\",\"#756bb1\",\"#fd8d3c\",\"#fd8d3c\",\"#756bb1\",\"#fd8d3c\",\"#fd8d3c\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#fd8d3c\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#fd8d3c\",\"#fd8d3c\",\"#756bb1\",\"#756bb1\",\"#fd8d3c\",\"#756bb1\",\"#fd8d3c\",\"#756bb1\",\"#fd8d3c\",\"#fd8d3c\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#fd8d3c\",\"#fd8d3c\",\"#756bb1\",\"#fd8d3c\",\"#756bb1\",\"#756bb1\",\"#fd8d3c\",\"#fd8d3c\",\"#fd8d3c\",\"#fd8d3c\",\"#fd8d3c\",\"#756bb1\",\"#756bb1\",\"#fd8d3c\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#fd8d3c\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#fd8d3c\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#fd8d3c\",\"#756bb1\",\"#756bb1\",\"#fd8d3c\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#fd8d3c\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#fd8d3c\",\"#756bb1\",\"#fd8d3c\",\"#fd8d3c\",\"#756bb1\",\"#756bb1\",\"#fd8d3c\",\"#fd8d3c\",\"#756bb1\",\"#fd8d3c\"],\"_formatted_exp_layer\":[\"9.47\",\"9.47\",\"9.47\",\"9.47\",\"9.47\",\"9.47\",\"9.47\",\"9.47\",\"9.47\",\"9.47\",\"9.47\",\"9.47\",\"9.47\",\"9.47\",\"9.47\",\"9.47\",\"9.47\",\"9.47\",\"9.47\",\"9.47\",\"9.47\",\"9.47\",\"9.47\",\"9.47\",\"5.69\",\"5.69\",\"5.69\",\"5.69\",\"5.69\",\"5.69\",\"5.69\",\"5.69\",\"5.69\",\"5.69\",\"5.69\",\"5.69\",\"5.69\",\"5.69\",\"5.69\",\"5.69\",\"5.69\",\"5.69\",\"5.69\",\"5.69\",\"5.69\",\"5.69\",\"5.69\",\"5.69\",\"4.64\",\"4.64\",\"4.64\",\"4.64\",\"4.64\",\"4.64\",\"4.64\",\"4.64\",\"4.64\",\"4.64\",\"4.64\",\"4.64\",\"4.64\",\"4.64\",\"4.64\",\"4.64\",\"4.64\",\"4.64\",\"4.64\",\"4.64\",\"4.64\",\"4.64\",\"4.64\",\"4.64\",\"3.79\",\"3.79\",\"3.79\",\"3.79\",\"3.79\",\"3.79\",\"3.79\",\"3.79\",\"3.79\",\"3.79\",\"3.79\",\"3.79\",\"3.79\",\"3.79\",\"3.79\",\"3.79\",\"3.79\",\"3.79\",\"3.79\",\"3.79\",\"3.79\",\"3.79\",\"3.79\",\"3.79\",\"3.39\",\"3.39\",\"3.39\",\"3.39\",\"3.39\",\"3.39\",\"3.39\",\"3.39\",\"3.39\",\"3.39\",\"3.39\",\"3.39\",\"3.39\",\"3.39\",\"3.39\",\"3.39\",\"3.39\",\"3.39\",\"3.39\",\"3.39\",\"3.39\",\"3.39\",\"3.39\",\"3.39\",\"9.40\",\"9.40\",\"9.40\",\"9.40\",\"9.40\",\"9.40\",\"9.40\",\"9.40\",\"9.40\",\"9.40\",\"9.40\",\"9.40\",\"9.40\",\"9.40\",\"9.40\",\"9.40\",\"9.40\",\"9.40\",\"9.40\",\"9.40\",\"9.40\",\"9.40\",\"9.40\",\"9.40\",\"9.93\",\"9.93\",\"9.93\",\"9.93\",\"9.93\",\"9.93\",\"9.93\",\"9.93\",\"9.93\",\"9.93\",\"9.93\",\"9.93\",\"9.93\",\"9.93\",\"9.93\",\"9.93\",\"9.93\",\"9.93\",\"9.93\",\"9.93\",\"9.93\",\"9.93\",\"9.93\",\"9.93\",\"6.54\",\"6.54\",\"6.54\",\"6.54\",\"6.54\",\"6.54\",\"6.54\",\"6.54\",\"6.54\",\"6.54\",\"6.54\",\"6.54\",\"6.54\",\"6.54\",\"6.54\",\"6.54\",\"6.54\",\"6.54\",\"6.54\",\"6.54\",\"6.54\",\"6.54\",\"6.54\",\"6.54\"],\"_formatted_kl_unif\":[\"K(\\u0394) = 0.60\",\"K(\\u0394) = 0.60\",\"K(\\u0394) = 0.60\",\"K(\\u0394) = 0.60\",\"K(\\u0394) = 0.60\",\"K(\\u0394) = 0.60\",\"K(\\u0394) = 0.60\",\"K(\\u0394) = 0.60\",\"K(\\u0394) = 0.60\",\"K(\\u0394) = 0.60\",\"K(\\u0394) = 0.60\",\"K(\\u0394) = 0.60\",\"K(\\u0394) = 0.60\",\"K(\\u0394) = 0.60\",\"K(\\u0394) = 0.60\",\"K(\\u0394) = 0.60\",\"K(\\u0394) = 0.60\",\"K(\\u0394) = 0.60\",\"K(\\u0394) = 0.60\",\"K(\\u0394) = 0.60\",\"K(\\u0394) = 0.60\",\"K(\\u0394) = 0.60\",\"K(\\u0394) = 0.60\",\"K(\\u0394) = 0.60\",\"K(\\u0394) = 1.15\",\"K(\\u0394) = 1.15\",\"K(\\u0394) = 1.15\",\"K(\\u0394) = 1.15\",\"K(\\u0394) = 1.15\",\"K(\\u0394) = 1.15\",\"K(\\u0394) = 1.15\",\"K(\\u0394) = 1.15\",\"K(\\u0394) = 1.15\",\"K(\\u0394) = 1.15\",\"K(\\u0394) = 1.15\",\"K(\\u0394) = 1.15\",\"K(\\u0394) = 1.15\",\"K(\\u0394) = 1.15\",\"K(\\u0394) = 1.15\",\"K(\\u0394) = 1.15\",\"K(\\u0394) = 1.15\",\"K(\\u0394) = 1.15\",\"K(\\u0394) = 1.15\",\"K(\\u0394) = 1.15\",\"K(\\u0394) = 1.15\",\"K(\\u0394) = 1.15\",\"K(\\u0394) = 1.15\",\"K(\\u0394) = 1.15\",\"K(\\u0394) = 1.61\",\"K(\\u0394) = 1.61\",\"K(\\u0394) = 1.61\",\"K(\\u0394) = 1.61\",\"K(\\u0394) = 1.61\",\"K(\\u0394) = 1.61\",\"K(\\u0394) = 1.61\",\"K(\\u0394) = 1.61\",\"K(\\u0394) = 1.61\",\"K(\\u0394) = 1.61\",\"K(\\u0394) = 1.61\",\"K(\\u0394) = 1.61\",\"K(\\u0394) = 1.61\",\"K(\\u0394) = 1.61\",\"K(\\u0394) = 1.61\",\"K(\\u0394) = 1.61\",\"K(\\u0394) = 1.61\",\"K(\\u0394) = 1.61\",\"K(\\u0394) = 1.61\",\"K(\\u0394) = 1.61\",\"K(\\u0394) = 1.61\",\"K(\\u0394) = 1.61\",\"K(\\u0394) = 1.61\",\"K(\\u0394) = 1.61\",\"K(\\u0394) = 1.57\",\"K(\\u0394) = 1.57\",\"K(\\u0394) = 1.57\",\"K(\\u0394) = 1.57\",\"K(\\u0394) = 1.57\",\"K(\\u0394) = 1.57\",\"K(\\u0394) = 1.57\",\"K(\\u0394) = 1.57\",\"K(\\u0394) = 1.57\",\"K(\\u0394) = 1.57\",\"K(\\u0394) = 1.57\",\"K(\\u0394) = 1.57\",\"K(\\u0394) = 1.57\",\"K(\\u0394) = 1.57\",\"K(\\u0394) = 1.57\",\"K(\\u0394) = 1.57\",\"K(\\u0394) = 1.57\",\"K(\\u0394) = 1.57\",\"K(\\u0394) = 1.57\",\"K(\\u0394) = 1.57\",\"K(\\u0394) = 1.57\",\"K(\\u0394) = 1.57\",\"K(\\u0394) = 1.57\",\"K(\\u0394) = 1.57\",\"K(\\u0394) = 1.60\",\"K(\\u0394) = 1.60\",\"K(\\u0394) = 1.60\",\"K(\\u0394) = 1.60\",\"K(\\u0394) = 1.60\",\"K(\\u0394) = 1.60\",\"K(\\u0394) = 1.60\",\"K(\\u0394) = 1.60\",\"K(\\u0394) = 1.60\",\"K(\\u0394) = 1.60\",\"K(\\u0394) = 1.60\",\"K(\\u0394) = 1.60\",\"K(\\u0394) = 1.60\",\"K(\\u0394) = 1.60\",\"K(\\u0394) = 1.60\",\"K(\\u0394) = 1.60\",\"K(\\u0394) = 1.60\",\"K(\\u0394) = 1.60\",\"K(\\u0394) = 1.60\",\"K(\\u0394) = 1.60\",\"K(\\u0394) = 1.60\",\"K(\\u0394) = 1.60\",\"K(\\u0394) = 1.60\",\"K(\\u0394) = 1.60\",\"K(\\u0394) = 0.50\",\"K(\\u0394) = 0.50\",\"K(\\u0394) = 0.50\",\"K(\\u0394) = 0.50\",\"K(\\u0394) = 0.50\",\"K(\\u0394) = 0.50\",\"K(\\u0394) = 0.50\",\"K(\\u0394) = 0.50\",\"K(\\u0394) = 0.50\",\"K(\\u0394) = 0.50\",\"K(\\u0394) = 0.50\",\"K(\\u0394) = 0.50\",\"K(\\u0394) = 0.50\",\"K(\\u0394) = 0.50\",\"K(\\u0394) = 0.50\",\"K(\\u0394) = 0.50\",\"K(\\u0394) = 0.50\",\"K(\\u0394) = 0.50\",\"K(\\u0394) = 0.50\",\"K(\\u0394) = 0.50\",\"K(\\u0394) = 0.50\",\"K(\\u0394) = 0.50\",\"K(\\u0394) = 0.50\",\"K(\\u0394) = 0.50\",\"K(\\u0394) = 0.33\",\"K(\\u0394) = 0.33\",\"K(\\u0394) = 0.33\",\"K(\\u0394) = 0.33\",\"K(\\u0394) = 0.33\",\"K(\\u0394) = 0.33\",\"K(\\u0394) = 0.33\",\"K(\\u0394) = 0.33\",\"K(\\u0394) = 0.33\",\"K(\\u0394) = 0.33\",\"K(\\u0394) = 0.33\",\"K(\\u0394) = 0.33\",\"K(\\u0394) = 0.33\",\"K(\\u0394) = 0.33\",\"K(\\u0394) = 0.33\",\"K(\\u0394) = 0.33\",\"K(\\u0394) = 0.33\",\"K(\\u0394) = 0.33\",\"K(\\u0394) = 0.33\",\"K(\\u0394) = 0.33\",\"K(\\u0394) = 0.33\",\"K(\\u0394) = 0.33\",\"K(\\u0394) = 0.33\",\"K(\\u0394) = 0.33\",\"K(\\u0394) = 1.31\",\"K(\\u0394) = 1.31\",\"K(\\u0394) = 1.31\",\"K(\\u0394) = 1.31\",\"K(\\u0394) = 1.31\",\"K(\\u0394) = 1.31\",\"K(\\u0394) = 1.31\",\"K(\\u0394) = 1.31\",\"K(\\u0394) = 1.31\",\"K(\\u0394) = 1.31\",\"K(\\u0394) = 1.31\",\"K(\\u0394) = 1.31\",\"K(\\u0394) = 1.31\",\"K(\\u0394) = 1.31\",\"K(\\u0394) = 1.31\",\"K(\\u0394) = 1.31\",\"K(\\u0394) = 1.31\",\"K(\\u0394) = 1.31\",\"K(\\u0394) = 1.31\",\"K(\\u0394) = 1.31\",\"K(\\u0394) = 1.31\",\"K(\\u0394) = 1.31\",\"K(\\u0394) = 1.31\",\"K(\\u0394) = 1.31\"],\"_line_color\":[\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#e6550d\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#e6550d\",\"#756bb1\",\"#756bb1\",\"#e6550d\",\"#e6550d\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#e6550d\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#e6550d\",\"#756bb1\",\"#e6550d\",\"#e6550d\",\"#756bb1\",\"#e6550d\",\"#756bb1\",\"#e6550d\",\"#e6550d\",\"#756bb1\",\"#756bb1\",\"#e6550d\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#e6550d\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#e6550d\",\"#756bb1\",\"#756bb1\",\"#e6550d\",\"#e6550d\",\"#756bb1\",\"#e6550d\",\"#e6550d\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#e6550d\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#e6550d\",\"#e6550d\",\"#756bb1\",\"#756bb1\",\"#e6550d\",\"#756bb1\",\"#e6550d\",\"#756bb1\",\"#e6550d\",\"#e6550d\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#e6550d\",\"#e6550d\",\"#756bb1\",\"#e6550d\",\"#756bb1\",\"#756bb1\",\"#e6550d\",\"#e6550d\",\"#e6550d\",\"#e6550d\",\"#e6550d\",\"#756bb1\",\"#756bb1\",\"#e6550d\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#e6550d\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#e6550d\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#e6550d\",\"#756bb1\",\"#756bb1\",\"#e6550d\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#e6550d\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#e6550d\",\"#756bb1\",\"#e6550d\",\"#e6550d\",\"#756bb1\",\"#756bb1\",\"#e6550d\",\"#e6550d\",\"#756bb1\",\"#e6550d\"],\"accuracy\":{\"__ndarray__\":\"oB9HXNx57T+V+aNBIJLtP4HL97tNlO0/W7M7X+y+7T99SyeuvsrtP9+eMj39y+0/UI2YRDDX7T8LPyf35e3tPxmpZsDl++0/cgfq41wR7j+ypG90IzXuP9ZtdnLqPO4/ZGF2uxFg7j+8jt4vlHnuP/n6SBFmoe4/8jbcVJOx7j/oEDk618nuPxpEfwGe3+4/kMU2Fq/e7j+7UqrQSNbuP5DFNhav3u4/tr9Yw2ri7j+2v1jDauLuP33IpT/R3O4/BRbEoPPa7z/6bmVhc93vP530V0CS3+8/T3iE+vXk7z9QkJJ61+XvP0YrCgSd5e8/8Kzv9K7m7z/J92I2IufvPxAtED3E5+8/FK6zIe3p7z9N63oEqezvP4OGMx6Z7u8/3YXxEbDv7z/Pdf1t6PDvP4cH1wLC8O8/UCpIIIzx7z+WR+emTPHvP6tKcfhF8e8/pof3Stfx7z9JFkeOt/HvP/YJH0jS8e8/FquqdIrx7z+TveZdYvHvPxk1q7108e8//9kVfVDH7z/bHOqb3sbvP1q3IuZvyO8/gbs9NA/M7z8Q5V1N+dDvP/pvKs6y0O8/l6OSSKDS7z/aAi3Gc9PvPySGw/Rc1O8/fFFShXHV7z+rgqjwK9nvP88/1NGd2e8/VPXJYD/b7z+mpZusQ9zvPzeaSjEL3u8/xoW6Sc3f7z+XkhTfOt/vP+UnKeYu4O8/BMqXgpDg7z/zbyFIWuDvP64HSF6B3+8/9HhgtF/g7z/qQuYqP+DvP4Y4nqQE3+8/aymEJd6V7z95TaCcLJvvP0DlVXkhne8/SIPXsKyp7z8LLfqCSazvP8T1SZfQrO8/KS3hO3Cr7z99MPSUCa3vP2oX5k+Tru8/oB7qcV+y7z+wumaI+rXvP3WiJWtquO8/cZhHM3a47z+dvaNwILjvP4qISv4Nue8/Yhe9PEK67z/INQwPk7fvP2ft3JtXuu8/DkxAPuG57z87OttHX7rvP/n2wxzZuO8/iRUb7k+37z/UqoqZkbjvP95yFYVYue8/OeW8qszj7z+H31nS6ejvP9XRQZ7D6u8/0TbAYR/u7z9SNRgSeO/vPz0d/l4x8O8/qEqEfTTx7z/cD6xAwvHvP8nJowH98e8/QIN70aHy7z/2pMNbtfPvPxGkldiC9O8/2lFBczH17z9mIzP2HPXvP+qAyby69O8/kAAt8Av17z8uGCeyvPTvP43prPrP9O8/DlK/DAP17z+HaV/z1PTvP3EM177T9O8/fAxyzcn07z8omNmqwfTvP6Vpp2+69O8/NyeQrdkb7z92cyhGVifvP/2lI+D6Iu8/MWteEhIu7z8Zfwp4YzbvPxahcap/P+8/0ZindjtG7z8/3052MUrvP6OemA/CTe8/Bl7iqFJR7z+rR12oQ1fvP5JbCQ6VX+8/yf7cDZBh7z/2GlOnJWPvP90u/wx3a+8/5dfDpfh07z/CZBKl5HzvP9hyzXGvfe8/UUDS1wqC7z/gG5IKMYfvP+ui73CWh+8/ppolPVKO7z9Z6ZZwjIvvP8cvPnCCj+8/E01GLxS46z+K/vDCjNTrP6+VpD153es/AbCbVgXx6z8jUYc/GPnrP1yxBlyxBuw/yns9Awoh7D/qIUUjsCjsPzw8PDw8POw/cqbzxvtI7D8+NyAFqTzsP+BwKm5UY+w/7khKtbpm7D80hgVQTXfsP1sYnZOmgOw/rTKUrDKU7D/7VsMz5absPzetCuJXtew/PZ62PJ627D90A1KQysPsP429yYy9yew/n4uxZf3N7D/LDvUDndjsP2kh+to9wew/Fbnqm7Se7z85cFZ6Eq/vP7a+sf5npu8/1XgbuvG07z/98ywhqLXvPxhUMtoUtu8/MFaoHzm67z+BeOZiTcDvPw4xn4oDvu8/k5D0M2vC7z9NI6yJkMjvP0VVw7iPye8/mbs/5LTN7z/9vY2x28/vP067Z1yyz+8/TLSwf0jR7z+R0wWIfNDvP5e0iAdLz+8/trHSV3XQ7z9QjnwirdHvP8+XyfmT0e8/5L1FhIXQ7z9taJDyZ9HvPwOFv6Vy0O8/\",\"dtype\":\"float64\",\"shape\":[192]},\"accuracy_errn95\":{\"__ndarray__\":\"I3yTc4araj9GNvu62zRqP5fzypgQKmo/bPM16ctRaT90KthEChRpPwj7VyN+DWk/QL5mZyjSaD99ccfhg1doP7LJawJMCmg/gQiXnV+RZz+9185WlMBmP5KakjLpkWY/9lwDCsq4ZT8hj09JZRRlP4+RKu3VBmQ/X1IbFVOUYz9lCw91geJiP9kPmsYiPGI/nnVgRGhDYj9IiLD2RIRiP551YERoQ2I/3gTIET4mYj/eBMgRPiZiP60QSDrpUWI/qKPaIX3EHj/anRV1XrcdP1TIuD8qyxw/UbN8PwpNGj8Dq4080d4ZP+J03j6S+xk/eXAQjLpzGT9dFtbmtTkZP5zm2bY+5xg/BuW7NVXFFz/IQBU2/EAWP2r+AuOqHBU/mFLKixFxFD9KhD2A7KkTPxLhnPnXwhM/IH3iEFI+Ez817yarUmgTP27+SzO5bBM/3m5JFRwMEz9udRCCXyETP3YcySh5DxM/ar88Nm4/Ez/iW7h6/lkTPx8aiELWTRM/2G1g/l0fMT//0s+caTAxPwfk664K9DA/ljiOWx9lMD8VDlkMrDUvP6UTtEjlTC8/xX67mdqoLj9H7MaCd2EuP01emz35ES4/IhyRApeyLT/G9FyQml8sP8cUTZ0SNiw/qWYdJqqbKz99rZu8pTkrP1U1456niio/DcA+ix/ZKT8e6UasZhMqP3yadNn6sSk/jnLvN5mKKT/ddnG2gaApP/V+VPpn9yk/XYYvuFGeKT9tjrzWbqspPxAG6czaKCo/32/GaV4AFT9k8WlG9XkUPyO0BCp6RxQ/j9Cxj732Ej/WXyrVe60SP4UnHrqLnhI/1gVT/mjFEj+WiXePOpgSP8N773dYbBI/WXIV5yH+ET/ClAeh4ZIRP3syeqLdSBE/ycFXpnRHET/TjPSQtVERP6bwrB0/NRE/HqinEgcQET/CrS06j2IRP52zJ1hvDRE/yOLJRMYbET+s+7n7gAwRPzROgFeZOxE/W0U+d4lqET+vnE+wLEQRP/Mo7RlHLBE/BQyTM7ohAD+EsuT9ejP9PnmKerZkAvw+uX3D5Fu0+T7hAXW5Orj4Ptm5XGdoLPg+tJEuWl5j9z4dZuLVcvL2PlleWa0Aw/Y+uMGgJMk79j5Ekcd5MlL1PmwuZhk6nfQ+UyEIdGb+8z51AtkDSxH0PizGRP3pavQ+9bW1EfAg9D5B4DNnJGn0PkHXqgmqV/Q+0pGEWhYp9D6IvUIKJlP0Po3H4l8+VPQ+zhX130Rd9D6XWf1LpGT0PsbfEsIva/Q+Eo4msfVeYj+XV78nWOphP8U3n9z2FmI/4DVYLGukYT//3PD4V0xhP7ebjima6WA/AEuCjv6eYD822Le8bXJgPx5QYYffSWA/p6G4weEgYD//PDQLHrdfP0tXMGSS8F4/OZNMfn/AXj/KVOMaz5leP4Z5jLY1y10/FVIQiHbXXD9iv8R1jAVcP5Su3+Qx8Fs/dTL/Q4N5Wz/uQpi0cepaP+Z9uNBO31o/pd4Os/oeWj/C+Mr+325aP+UDb2Vt/Fk/GWL4AeGucz8v6A5B9nZzP53rrkUyZXM/9TScf989cz97xHD4di1zPwaTU0GbEXM/hSJ3U9Hacj+ZkULGtMpyP8oPkl4aoXI/SEk+06GFcj8JJiEQMaByP5YmA1P9S3I/BbZk+XZEcj9Y57F2fR9yP7mEYpZqCnI/grL+d9bdcT/s9wmCh7JxPwmHUqyakHE/+1coWpeNcT8S9Ey3RG5xP54REjMCYHE/ibXFbMdVcT+HVIn1CjxxP2BTVqFbdHE/z6JDcYM3Ij8f5q3xhKEgP9wSFEhIfSE/AEbxKqIFID+MhS1kmOQfPwLlhjt0zR8/RcH6dRnoHj8dHOrBaYodPxbeckH6Dx4/Ps1asK4MHT+dgqslgZIbP/GcLwsvUxs/h0QgK01FGj9R13gzvrQZP8DDgha0vxk/LVeOlS5TGT8S1nnN6YkZPya7kP0F2xk/DdakZtWLGT/7v5PGADgZP+cezgjPPhk/Q6/JGIOHGT+RDaB6s0oZP862VLaNjBk/\",\"dtype\":\"float64\",\"shape\":[192]},\"contextual_headroom\":[0.11639055893469108,0.11639055893469108,0.11639055893469108,0.11639055893469108,0.11639055893469108,0.11639055893469108,0.11639055893469108,0.11639055893469108,0.11639055893469108,0.11639055893469108,0.11639055893469108,0.11639055893469108,0.11639055893469108,0.11639055893469108,0.11639055893469108,0.11639055893469108,0.11639055893469108,0.11639055893469108,0.11639055893469108,0.11639055893469108,0.11639055893469108,0.11639055893469108,0.11639055893469108,0.11639055893469108,0.09997559540642187,0.09997559540642187,0.09997559540642187,0.09997559540642187,0.09997559540642187,0.09997559540642187,0.09997559540642187,0.09997559540642187,0.09997559540642187,0.09997559540642187,0.09997559540642187,0.09997559540642187,0.09997559540642187,0.09997559540642187,0.09997559540642187,0.09997559540642187,0.09997559540642187,0.09997559540642187,0.09997559540642187,0.09997559540642187,0.09997559540642187,0.09997559540642187,0.09997559540642187,0.09997559540642187,0.05733773727377656,0.05733773727377656,0.05733773727377656,0.05733773727377656,0.05733773727377656,0.05733773727377656,0.05733773727377656,0.05733773727377656,0.05733773727377656,0.05733773727377656,0.05733773727377656,0.05733773727377656,0.05733773727377656,0.05733773727377656,0.05733773727377656,0.05733773727377656,0.05733773727377656,0.05733773727377656,0.05733773727377656,0.05733773727377656,0.05733773727377656,0.05733773727377656,0.05733773727377656,0.05733773727377656,0.1369172609382292,0.1369172609382292,0.1369172609382292,0.1369172609382292,0.1369172609382292,0.1369172609382292,0.1369172609382292,0.1369172609382292,0.1369172609382292,0.1369172609382292,0.1369172609382292,0.1369172609382292,0.1369172609382292,0.1369172609382292,0.1369172609382292,0.1369172609382292,0.1369172609382292,0.1369172609382292,0.1369172609382292,0.1369172609382292,0.1369172609382292,0.1369172609382292,0.1369172609382292,0.1369172609382292,0.08318042260149905,0.08318042260149905,0.08318042260149905,0.08318042260149905,0.08318042260149905,0.08318042260149905,0.08318042260149905,0.08318042260149905,0.08318042260149905,0.08318042260149905,0.08318042260149905,0.08318042260149905,0.08318042260149905,0.08318042260149905,0.08318042260149905,0.08318042260149905,0.08318042260149905,0.08318042260149905,0.08318042260149905,0.08318042260149905,0.08318042260149905,0.08318042260149905,0.08318042260149905,0.08318042260149905,0.23439707290638978,0.23439707290638978,0.23439707290638978,0.23439707290638978,0.23439707290638978,0.23439707290638978,0.23439707290638978,0.23439707290638978,0.23439707290638978,0.23439707290638978,0.23439707290638978,0.23439707290638978,0.23439707290638978,0.23439707290638978,0.23439707290638978,0.23439707290638978,0.23439707290638978,0.23439707290638978,0.23439707290638978,0.23439707290638978,0.23439707290638978,0.23439707290638978,0.23439707290638978,0.23439707290638978,0.06260312292920267,0.06260312292920267,0.06260312292920267,0.06260312292920267,0.06260312292920267,0.06260312292920267,0.06260312292920267,0.06260312292920267,0.06260312292920267,0.06260312292920267,0.06260312292920267,0.06260312292920267,0.06260312292920267,0.06260312292920267,0.06260312292920267,0.06260312292920267,0.06260312292920267,0.06260312292920267,0.06260312292920267,0.06260312292920267,0.06260312292920267,0.06260312292920267,0.06260312292920267,0.06260312292920267,0.10353468382410691,0.10353468382410691,0.10353468382410691,0.10353468382410691,0.10353468382410691,0.10353468382410691,0.10353468382410691,0.10353468382410691,0.10353468382410691,0.10353468382410691,0.10353468382410691,0.10353468382410691,0.10353468382410691,0.10353468382410691,0.10353468382410691,0.10353468382410691,0.10353468382410691,0.10353468382410691,0.10353468382410691,0.10353468382410691,0.10353468382410691,0.10353468382410691,0.10353468382410691,0.10353468382410691],\"delta_score\":[0.013879441257917402,0.004651805956420341,0.0019949832561770853,0.012973188412789494,0.003535951670998738,-0.0003702407581366307,0.003854913478508748,0.007628730540243489,0.0032027459523230606,0.006833033344139872,0.010519605663694698,0.0015124410673706956,0.010471796336309458,0.006697584774402521,0.010958802965727377,0.004426884538286768,0.006403926892257106,0.006034720166532503,0.00010718428834255445,-0.0023865592874846575,0.0020825865972845525,0.0013770892203930352,-0.00016324335843065363,-0.0015092368295099856,0.02552338412121402,0.008569574507726108,0.007055262072416357,0.017791407828561145,0.0028806265752692184,-0.0008405908876449875,0.003441958198510009,0.0014829754309192422,0.00200736152590697,0.006975476846320716,0.008762393481853148,0.0061971665344429105,0.003380222973357938,0.003835858678077675,-0.0004752391681167589,0.0024782240535842215,-0.0007424787750688333,-9.31750350343652e-05,0.001745151356686736,-0.0003600133125067906,0.0003163571601318971,-0.0008474913440715826,-0.0005003885662981933,0.0002148349005205441,0.02747614170542223,-0.0005671336455403964,0.0019544774873441195,0.004311809685775048,0.005848448076223534,-0.00032336250990172566,0.0022446630826036262,0.0009699948096050237,0.0010157682989533345,0.0013175406411705115,0.004413022262864885,0.00048733796082711667,0.0019009168018350175,0.0012462807948429022,0.0020964911351403215,0.0020465302514487416,-0.0006928534156666055,0.0011414027393170656,0.00045025094750783534,-0.0002690046481890196,-0.0010058683529091672,0.0010132547474859255,-0.00015577883683715044,-0.0014692815263527281,0.05941261708359613,0.011048502584685815,0.004677767840125413,0.02698045911417002,0.005588037376253352,0.0006848171085261923,-0.0022263614877978677,0.0036037674074740345,0.003680337968767655,0.0077610405887247325,0.007102365457741455,0.005642029694835293,-0.0011247324085661425,-0.0008636008267759454,0.0010530576228330313,0.0031726639764402265,-0.004976981917454881,0.005701492956110887,-0.0011557425120003462,0.0009323786396909783,-0.0038786941524872054,-0.001788927583590283,0.0019961060253524954,0.0009686456541324606,0.03147784041096369,0.015209346190759088,0.005542698806958457,0.01006439317583152,0.003975623955219332,0.0021267767882398037,0.0030142324732994608,0.0016426685079516945,0.0006818248203487309,0.001887400396825334,0.003162874383283776,0.002363190365777923,0.002031677022008127,-0.00025292474215765637,-0.0011504127298819222,0.0009539925309216546,-0.0009076714488512883,0.00021502250903249198,0.0005958623098627491,-0.0005398029488270506,-1.1122820999132088e-05,-0.00011931107103668737,-8.414386688015973e-05,-7.716398841250971e-05,0.038022716937981205,0.009133392094210269,-0.0014685009842487773,0.02812200390187991,0.007958259645146293,0.019217976144238813,0.013708396076661522,0.007849365174594891,0.008834904702282875,0.004181190899440135,0.00889109356420037,0.013741023946374331,0.0005925911211828172,0.005280717002877577,0.011999615660160057,0.01595168385661072,0.012510997656734912,0.0021943021049737332,0.008327165529048552,0.008114978132677364,0.001582816029121914,0.009129031066018478,-0.005052830263922337,0.005574110691895617,0.0045373382940604445,0.0035109095276679714,0.002656923969406866,0.006183731894206845,0.0018637948512387759,0.0027671747625778176,0.0019921310192352326,0.002826112654943258,0.003686419136993635,0.0034318410937509425,0.0013004966003941076,0.005453021157068916,-0.00028402195260857077,0.0027035759719707952,0.002231485705491698,0.0057127368043372595,0.0019703335278200562,0.0024232025207228114,0.0008098536363528863,0.0019369122123800153,0.0032332580535665567,0.00018571629285113467,0.0014701719452714368,-0.0020228431766619037,0.004584003207641407,0.032558127296263395,-0.017554504694995754,0.028778523180469584,0.0016022635029485643,0.0007650167744763792,0.008303272287720986,0.011806069119540519,-0.004461980190427761,0.008323213123796913,0.011910157364277807,0.0014559550602089022,0.007994227309569446,0.004114361373145803,-0.0003620136732909174,0.0030759169179565005,-0.0014608450094321102,-0.002147781713638053,0.0020261541165566,0.0022246330149062743,-5.350895643019271e-06,-0.0021271871530643693,0.0018086290640578762,-0.0019309952916636286],\"display_col\":[\"bert-large-uncased-mix-01 (base)\",\"bert-large-uncased-mix-02 (base)\",\"bert-large-uncased-mix-03 (base)\",\"bert-large-uncased-mix-04 (base)\",\"bert-large-uncased-mix-05 (base)\",\"bert-large-uncased-mix-06 (base)\",\"bert-large-uncased-mix-07 (base)\",\"bert-large-uncased-mix-08 (base)\",\"bert-large-uncased-mix-09 (base)\",\"bert-large-uncased-mix-10 (base)\",\"bert-large-uncased-mix-11 (base)\",\"bert-large-uncased-mix-12 (base)\",\"bert-large-uncased-mix-13 (base)\",\"bert-large-uncased-mix-14 (base)\",\"bert-large-uncased-mix-15 (base)\",\"bert-large-uncased-mix-16 (base)\",\"bert-large-uncased-mix-17 (base)\",\"bert-large-uncased-mix-18 (base)\",\"bert-large-uncased-mix-19 (base)\",\"bert-large-uncased-mix-20 (base)\",\"bert-large-uncased-mix-21 (base)\",\"bert-large-uncased-mix-22 (base)\",\"bert-large-uncased-mix-23 (base)\",\"bert-large-uncased-mix-24 (base)\",\"bert-large-uncased-mix-01 (base)\",\"bert-large-uncased-mix-02 (base)\",\"bert-large-uncased-mix-03 (base)\",\"bert-large-uncased-mix-04 (base)\",\"bert-large-uncased-mix-05 (base)\",\"bert-large-uncased-mix-06 (base)\",\"bert-large-uncased-mix-07 (base)\",\"bert-large-uncased-mix-08 (base)\",\"bert-large-uncased-mix-09 (base)\",\"bert-large-uncased-mix-10 (base)\",\"bert-large-uncased-mix-11 (base)\",\"bert-large-uncased-mix-12 (base)\",\"bert-large-uncased-mix-13 (base)\",\"bert-large-uncased-mix-14 (base)\",\"bert-large-uncased-mix-15 (base)\",\"bert-large-uncased-mix-16 (base)\",\"bert-large-uncased-mix-17 (base)\",\"bert-large-uncased-mix-18 (base)\",\"bert-large-uncased-mix-19 (base)\",\"bert-large-uncased-mix-20 (base)\",\"bert-large-uncased-mix-21 (base)\",\"bert-large-uncased-mix-22 (base)\",\"bert-large-uncased-mix-23 (base)\",\"bert-large-uncased-mix-24 (base)\",\"bert-large-uncased-mix-01 (base)\",\"bert-large-uncased-mix-02 (base)\",\"bert-large-uncased-mix-03 (base)\",\"bert-large-uncased-mix-04 (base)\",\"bert-large-uncased-mix-05 (base)\",\"bert-large-uncased-mix-06 (base)\",\"bert-large-uncased-mix-07 (base)\",\"bert-large-uncased-mix-08 (base)\",\"bert-large-uncased-mix-09 (base)\",\"bert-large-uncased-mix-10 (base)\",\"bert-large-uncased-mix-11 (base)\",\"bert-large-uncased-mix-12 (base)\",\"bert-large-uncased-mix-13 (base)\",\"bert-large-uncased-mix-14 (base)\",\"bert-large-uncased-mix-15 (base)\",\"bert-large-uncased-mix-16 (base)\",\"bert-large-uncased-mix-17 (base)\",\"bert-large-uncased-mix-18 (base)\",\"bert-large-uncased-mix-19 (base)\",\"bert-large-uncased-mix-20 (base)\",\"bert-large-uncased-mix-21 (base)\",\"bert-large-uncased-mix-22 (base)\",\"bert-large-uncased-mix-23 (base)\",\"bert-large-uncased-mix-24 (base)\",\"bert-large-uncased-mix-01 (base)\",\"bert-large-uncased-mix-02 (base)\",\"bert-large-uncased-mix-03 (base)\",\"bert-large-uncased-mix-04 (base)\",\"bert-large-uncased-mix-05 (base)\",\"bert-large-uncased-mix-06 (base)\",\"bert-large-uncased-mix-07 (base)\",\"bert-large-uncased-mix-08 (base)\",\"bert-large-uncased-mix-09 (base)\",\"bert-large-uncased-mix-10 (base)\",\"bert-large-uncased-mix-11 (base)\",\"bert-large-uncased-mix-12 (base)\",\"bert-large-uncased-mix-13 (base)\",\"bert-large-uncased-mix-14 (base)\",\"bert-large-uncased-mix-15 (base)\",\"bert-large-uncased-mix-16 (base)\",\"bert-large-uncased-mix-17 (base)\",\"bert-large-uncased-mix-18 (base)\",\"bert-large-uncased-mix-19 (base)\",\"bert-large-uncased-mix-20 (base)\",\"bert-large-uncased-mix-21 (base)\",\"bert-large-uncased-mix-22 (base)\",\"bert-large-uncased-mix-23 (base)\",\"bert-large-uncased-mix-24 (base)\",\"bert-large-uncased-mix-01 (base)\",\"bert-large-uncased-mix-02 (base)\",\"bert-large-uncased-mix-03 (base)\",\"bert-large-uncased-mix-04 (base)\",\"bert-large-uncased-mix-05 (base)\",\"bert-large-uncased-mix-06 (base)\",\"bert-large-uncased-mix-07 (base)\",\"bert-large-uncased-mix-08 (base)\",\"bert-large-uncased-mix-09 (base)\",\"bert-large-uncased-mix-10 (base)\",\"bert-large-uncased-mix-11 (base)\",\"bert-large-uncased-mix-12 (base)\",\"bert-large-uncased-mix-13 (base)\",\"bert-large-uncased-mix-14 (base)\",\"bert-large-uncased-mix-15 (base)\",\"bert-large-uncased-mix-16 (base)\",\"bert-large-uncased-mix-17 (base)\",\"bert-large-uncased-mix-18 (base)\",\"bert-large-uncased-mix-19 (base)\",\"bert-large-uncased-mix-20 (base)\",\"bert-large-uncased-mix-21 (base)\",\"bert-large-uncased-mix-22 (base)\",\"bert-large-uncased-mix-23 (base)\",\"bert-large-uncased-mix-24 (base)\",\"bert-large-uncased-mix-01 (base)\",\"bert-large-uncased-mix-02 (base)\",\"bert-large-uncased-mix-03 (base)\",\"bert-large-uncased-mix-04 (base)\",\"bert-large-uncased-mix-05 (base)\",\"bert-large-uncased-mix-06 (base)\",\"bert-large-uncased-mix-07 (base)\",\"bert-large-uncased-mix-08 (base)\",\"bert-large-uncased-mix-09 (base)\",\"bert-large-uncased-mix-10 (base)\",\"bert-large-uncased-mix-11 (base)\",\"bert-large-uncased-mix-12 (base)\",\"bert-large-uncased-mix-13 (base)\",\"bert-large-uncased-mix-14 (base)\",\"bert-large-uncased-mix-15 (base)\",\"bert-large-uncased-mix-16 (base)\",\"bert-large-uncased-mix-17 (base)\",\"bert-large-uncased-mix-18 (base)\",\"bert-large-uncased-mix-19 (base)\",\"bert-large-uncased-mix-20 (base)\",\"bert-large-uncased-mix-21 (base)\",\"bert-large-uncased-mix-22 (base)\",\"bert-large-uncased-mix-23 (base)\",\"bert-large-uncased-mix-24 (base)\",\"bert-large-uncased-mix-01 (base)\",\"bert-large-uncased-mix-02 (base)\",\"bert-large-uncased-mix-03 (base)\",\"bert-large-uncased-mix-04 (base)\",\"bert-large-uncased-mix-05 (base)\",\"bert-large-uncased-mix-06 (base)\",\"bert-large-uncased-mix-07 (base)\",\"bert-large-uncased-mix-08 (base)\",\"bert-large-uncased-mix-09 (base)\",\"bert-large-uncased-mix-10 (base)\",\"bert-large-uncased-mix-11 (base)\",\"bert-large-uncased-mix-12 (base)\",\"bert-large-uncased-mix-13 (base)\",\"bert-large-uncased-mix-14 (base)\",\"bert-large-uncased-mix-15 (base)\",\"bert-large-uncased-mix-16 (base)\",\"bert-large-uncased-mix-17 (base)\",\"bert-large-uncased-mix-18 (base)\",\"bert-large-uncased-mix-19 (base)\",\"bert-large-uncased-mix-20 (base)\",\"bert-large-uncased-mix-21 (base)\",\"bert-large-uncased-mix-22 (base)\",\"bert-large-uncased-mix-23 (base)\",\"bert-large-uncased-mix-24 (base)\",\"bert-large-uncased-mix-01 (base)\",\"bert-large-uncased-mix-02 (base)\",\"bert-large-uncased-mix-03 (base)\",\"bert-large-uncased-mix-04 (base)\",\"bert-large-uncased-mix-05 (base)\",\"bert-large-uncased-mix-06 (base)\",\"bert-large-uncased-mix-07 (base)\",\"bert-large-uncased-mix-08 (base)\",\"bert-large-uncased-mix-09 (base)\",\"bert-large-uncased-mix-10 (base)\",\"bert-large-uncased-mix-11 (base)\",\"bert-large-uncased-mix-12 (base)\",\"bert-large-uncased-mix-13 (base)\",\"bert-large-uncased-mix-14 (base)\",\"bert-large-uncased-mix-15 (base)\",\"bert-large-uncased-mix-16 (base)\",\"bert-large-uncased-mix-17 (base)\",\"bert-large-uncased-mix-18 (base)\",\"bert-large-uncased-mix-19 (base)\",\"bert-large-uncased-mix-20 (base)\",\"bert-large-uncased-mix-21 (base)\",\"bert-large-uncased-mix-22 (base)\",\"bert-large-uncased-mix-23 (base)\",\"bert-large-uncased-mix-24 (base)\"],\"display_row\":[\"coref-ontonotes-conll-1\",\"coref-ontonotes-conll-1\",\"coref-ontonotes-conll-1\",\"coref-ontonotes-conll-1\",\"coref-ontonotes-conll-1\",\"coref-ontonotes-conll-1\",\"coref-ontonotes-conll-1\",\"coref-ontonotes-conll-1\",\"coref-ontonotes-conll-1\",\"coref-ontonotes-conll-1\",\"coref-ontonotes-conll-1\",\"coref-ontonotes-conll-1\",\"coref-ontonotes-conll-1\",\"coref-ontonotes-conll-1\",\"coref-ontonotes-conll-1\",\"coref-ontonotes-conll-1\",\"coref-ontonotes-conll-1\",\"coref-ontonotes-conll-1\",\"coref-ontonotes-conll-1\",\"coref-ontonotes-conll-1\",\"coref-ontonotes-conll-1\",\"coref-ontonotes-conll-1\",\"coref-ontonotes-conll-1\",\"coref-ontonotes-conll-1\",\"dep-labeling-ewt-_micro_avg_\",\"dep-labeling-ewt-_micro_avg_\",\"dep-labeling-ewt-_micro_avg_\",\"dep-labeling-ewt-_micro_avg_\",\"dep-labeling-ewt-_micro_avg_\",\"dep-labeling-ewt-_micro_avg_\",\"dep-labeling-ewt-_micro_avg_\",\"dep-labeling-ewt-_micro_avg_\",\"dep-labeling-ewt-_micro_avg_\",\"dep-labeling-ewt-_micro_avg_\",\"dep-labeling-ewt-_micro_avg_\",\"dep-labeling-ewt-_micro_avg_\",\"dep-labeling-ewt-_micro_avg_\",\"dep-labeling-ewt-_micro_avg_\",\"dep-labeling-ewt-_micro_avg_\",\"dep-labeling-ewt-_micro_avg_\",\"dep-labeling-ewt-_micro_avg_\",\"dep-labeling-ewt-_micro_avg_\",\"dep-labeling-ewt-_micro_avg_\",\"dep-labeling-ewt-_micro_avg_\",\"dep-labeling-ewt-_micro_avg_\",\"dep-labeling-ewt-_micro_avg_\",\"dep-labeling-ewt-_micro_avg_\",\"dep-labeling-ewt-_micro_avg_\",\"ner-ontonotes-_micro_avg_\",\"ner-ontonotes-_micro_avg_\",\"ner-ontonotes-_micro_avg_\",\"ner-ontonotes-_micro_avg_\",\"ner-ontonotes-_micro_avg_\",\"ner-ontonotes-_micro_avg_\",\"ner-ontonotes-_micro_avg_\",\"ner-ontonotes-_micro_avg_\",\"ner-ontonotes-_micro_avg_\",\"ner-ontonotes-_micro_avg_\",\"ner-ontonotes-_micro_avg_\",\"ner-ontonotes-_micro_avg_\",\"ner-ontonotes-_micro_avg_\",\"ner-ontonotes-_micro_avg_\",\"ner-ontonotes-_micro_avg_\",\"ner-ontonotes-_micro_avg_\",\"ner-ontonotes-_micro_avg_\",\"ner-ontonotes-_micro_avg_\",\"ner-ontonotes-_micro_avg_\",\"ner-ontonotes-_micro_avg_\",\"ner-ontonotes-_micro_avg_\",\"ner-ontonotes-_micro_avg_\",\"ner-ontonotes-_micro_avg_\",\"ner-ontonotes-_micro_avg_\",\"nonterminal-ontonotes-_micro_avg_\",\"nonterminal-ontonotes-_micro_avg_\",\"nonterminal-ontonotes-_micro_avg_\",\"nonterminal-ontonotes-_micro_avg_\",\"nonterminal-ontonotes-_micro_avg_\",\"nonterminal-ontonotes-_micro_avg_\",\"nonterminal-ontonotes-_micro_avg_\",\"nonterminal-ontonotes-_micro_avg_\",\"nonterminal-ontonotes-_micro_avg_\",\"nonterminal-ontonotes-_micro_avg_\",\"nonterminal-ontonotes-_micro_avg_\",\"nonterminal-ontonotes-_micro_avg_\",\"nonterminal-ontonotes-_micro_avg_\",\"nonterminal-ontonotes-_micro_avg_\",\"nonterminal-ontonotes-_micro_avg_\",\"nonterminal-ontonotes-_micro_avg_\",\"nonterminal-ontonotes-_micro_avg_\",\"nonterminal-ontonotes-_micro_avg_\",\"nonterminal-ontonotes-_micro_avg_\",\"nonterminal-ontonotes-_micro_avg_\",\"nonterminal-ontonotes-_micro_avg_\",\"nonterminal-ontonotes-_micro_avg_\",\"nonterminal-ontonotes-_micro_avg_\",\"nonterminal-ontonotes-_micro_avg_\",\"pos-ontonotes-_micro_avg_\",\"pos-ontonotes-_micro_avg_\",\"pos-ontonotes-_micro_avg_\",\"pos-ontonotes-_micro_avg_\",\"pos-ontonotes-_micro_avg_\",\"pos-ontonotes-_micro_avg_\",\"pos-ontonotes-_micro_avg_\",\"pos-ontonotes-_micro_avg_\",\"pos-ontonotes-_micro_avg_\",\"pos-ontonotes-_micro_avg_\",\"pos-ontonotes-_micro_avg_\",\"pos-ontonotes-_micro_avg_\",\"pos-ontonotes-_micro_avg_\",\"pos-ontonotes-_micro_avg_\",\"pos-ontonotes-_micro_avg_\",\"pos-ontonotes-_micro_avg_\",\"pos-ontonotes-_micro_avg_\",\"pos-ontonotes-_micro_avg_\",\"pos-ontonotes-_micro_avg_\",\"pos-ontonotes-_micro_avg_\",\"pos-ontonotes-_micro_avg_\",\"pos-ontonotes-_micro_avg_\",\"pos-ontonotes-_micro_avg_\",\"pos-ontonotes-_micro_avg_\",\"rel-semeval-_clean_micro_\",\"rel-semeval-_clean_micro_\",\"rel-semeval-_clean_micro_\",\"rel-semeval-_clean_micro_\",\"rel-semeval-_clean_micro_\",\"rel-semeval-_clean_micro_\",\"rel-semeval-_clean_micro_\",\"rel-semeval-_clean_micro_\",\"rel-semeval-_clean_micro_\",\"rel-semeval-_clean_micro_\",\"rel-semeval-_clean_micro_\",\"rel-semeval-_clean_micro_\",\"rel-semeval-_clean_micro_\",\"rel-semeval-_clean_micro_\",\"rel-semeval-_clean_micro_\",\"rel-semeval-_clean_micro_\",\"rel-semeval-_clean_micro_\",\"rel-semeval-_clean_micro_\",\"rel-semeval-_clean_micro_\",\"rel-semeval-_clean_micro_\",\"rel-semeval-_clean_micro_\",\"rel-semeval-_clean_micro_\",\"rel-semeval-_clean_micro_\",\"rel-semeval-_clean_micro_\",\"spr1-_micro_avg_\",\"spr1-_micro_avg_\",\"spr1-_micro_avg_\",\"spr1-_micro_avg_\",\"spr1-_micro_avg_\",\"spr1-_micro_avg_\",\"spr1-_micro_avg_\",\"spr1-_micro_avg_\",\"spr1-_micro_avg_\",\"spr1-_micro_avg_\",\"spr1-_micro_avg_\",\"spr1-_micro_avg_\",\"spr1-_micro_avg_\",\"spr1-_micro_avg_\",\"spr1-_micro_avg_\",\"spr1-_micro_avg_\",\"spr1-_micro_avg_\",\"spr1-_micro_avg_\",\"spr1-_micro_avg_\",\"spr1-_micro_avg_\",\"spr1-_micro_avg_\",\"spr1-_micro_avg_\",\"spr1-_micro_avg_\",\"spr1-_micro_avg_\",\"srl-conll2012-_clean_micro_\",\"srl-conll2012-_clean_micro_\",\"srl-conll2012-_clean_micro_\",\"srl-conll2012-_clean_micro_\",\"srl-conll2012-_clean_micro_\",\"srl-conll2012-_clean_micro_\",\"srl-conll2012-_clean_micro_\",\"srl-conll2012-_clean_micro_\",\"srl-conll2012-_clean_micro_\",\"srl-conll2012-_clean_micro_\",\"srl-conll2012-_clean_micro_\",\"srl-conll2012-_clean_micro_\",\"srl-conll2012-_clean_micro_\",\"srl-conll2012-_clean_micro_\",\"srl-conll2012-_clean_micro_\",\"srl-conll2012-_clean_micro_\",\"srl-conll2012-_clean_micro_\",\"srl-conll2012-_clean_micro_\",\"srl-conll2012-_clean_micro_\",\"srl-conll2012-_clean_micro_\",\"srl-conll2012-_clean_micro_\",\"srl-conll2012-_clean_micro_\",\"srl-conll2012-_clean_micro_\",\"srl-conll2012-_clean_micro_\"],\"exp_layer\":[9.471179711705389,9.471179711705389,9.471179711705389,9.471179711705389,9.471179711705389,9.471179711705389,9.471179711705389,9.471179711705389,9.471179711705389,9.471179711705389,9.471179711705389,9.471179711705389,9.471179711705389,9.471179711705389,9.471179711705389,9.471179711705389,9.471179711705389,9.471179711705389,9.471179711705389,9.471179711705389,9.471179711705389,9.471179711705389,9.471179711705389,9.471179711705389,5.691932390197615,5.691932390197615,5.691932390197615,5.691932390197615,5.691932390197615,5.691932390197615,5.691932390197615,5.691932390197615,5.691932390197615,5.691932390197615,5.691932390197615,5.691932390197615,5.691932390197615,5.691932390197615,5.691932390197615,5.691932390197615,5.691932390197615,5.691932390197615,5.691932390197615,5.691932390197615,5.691932390197615,5.691932390197615,5.691932390197615,5.691932390197615,4.644666882875676,4.644666882875676,4.644666882875676,4.644666882875676,4.644666882875676,4.644666882875676,4.644666882875676,4.644666882875676,4.644666882875676,4.644666882875676,4.644666882875676,4.644666882875676,4.644666882875676,4.644666882875676,4.644666882875676,4.644666882875676,4.644666882875676,4.644666882875676,4.644666882875676,4.644666882875676,4.644666882875676,4.644666882875676,4.644666882875676,4.644666882875676,3.792980575634427,3.792980575634427,3.792980575634427,3.792980575634427,3.792980575634427,3.792980575634427,3.792980575634427,3.792980575634427,3.792980575634427,3.792980575634427,3.792980575634427,3.792980575634427,3.792980575634427,3.792980575634427,3.792980575634427,3.792980575634427,3.792980575634427,3.792980575634427,3.792980575634427,3.792980575634427,3.792980575634427,3.792980575634427,3.792980575634427,3.792980575634427,3.386439579545165,3.386439579545165,3.386439579545165,3.386439579545165,3.386439579545165,3.386439579545165,3.386439579545165,3.386439579545165,3.386439579545165,3.386439579545165,3.386439579545165,3.386439579545165,3.386439579545165,3.386439579545165,3.386439579545165,3.386439579545165,3.386439579545165,3.386439579545165,3.386439579545165,3.386439579545165,3.386439579545165,3.386439579545165,3.386439579545165,3.386439579545165,9.40046847774628,9.40046847774628,9.40046847774628,9.40046847774628,9.40046847774628,9.40046847774628,9.40046847774628,9.40046847774628,9.40046847774628,9.40046847774628,9.40046847774628,9.40046847774628,9.40046847774628,9.40046847774628,9.40046847774628,9.40046847774628,9.40046847774628,9.40046847774628,9.40046847774628,9.40046847774628,9.40046847774628,9.40046847774628,9.40046847774628,9.40046847774628,9.928992732451892,9.928992732451892,9.928992732451892,9.928992732451892,9.928992732451892,9.928992732451892,9.928992732451892,9.928992732451892,9.928992732451892,9.928992732451892,9.928992732451892,9.928992732451892,9.928992732451892,9.928992732451892,9.928992732451892,9.928992732451892,9.928992732451892,9.928992732451892,9.928992732451892,9.928992732451892,9.928992732451892,9.928992732451892,9.928992732451892,9.928992732451892,6.536649198760027,6.536649198760027,6.536649198760027,6.536649198760027,6.536649198760027,6.536649198760027,6.536649198760027,6.536649198760027,6.536649198760027,6.536649198760027,6.536649198760027,6.536649198760027,6.536649198760027,6.536649198760027,6.536649198760027,6.536649198760027,6.536649198760027,6.536649198760027,6.536649198760027,6.536649198760027,6.536649198760027,6.536649198760027,6.536649198760027,6.536649198760027],\"exp_name\":[\"bert-large-uncased-mix-01-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-02-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-03-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-04-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-05-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-06-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-07-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-08-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-09-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-10-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-11-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-12-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-13-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-14-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-15-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-16-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-17-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-18-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-19-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-20-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-21-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-22-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-23-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-24-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-01-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-02-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-03-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-04-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-05-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-06-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-07-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-08-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-09-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-10-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-11-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-12-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-13-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-14-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-15-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-16-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-17-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-18-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-19-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-20-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-21-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-22-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-23-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-24-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-01-edges-ner-ontonotes\",\"bert-large-uncased-mix-02-edges-ner-ontonotes\",\"bert-large-uncased-mix-03-edges-ner-ontonotes\",\"bert-large-uncased-mix-04-edges-ner-ontonotes\",\"bert-large-uncased-mix-05-edges-ner-ontonotes\",\"bert-large-uncased-mix-06-edges-ner-ontonotes\",\"bert-large-uncased-mix-07-edges-ner-ontonotes\",\"bert-large-uncased-mix-08-edges-ner-ontonotes\",\"bert-large-uncased-mix-09-edges-ner-ontonotes\",\"bert-large-uncased-mix-10-edges-ner-ontonotes\",\"bert-large-uncased-mix-11-edges-ner-ontonotes\",\"bert-large-uncased-mix-12-edges-ner-ontonotes\",\"bert-large-uncased-mix-13-edges-ner-ontonotes\",\"bert-large-uncased-mix-14-edges-ner-ontonotes\",\"bert-large-uncased-mix-15-edges-ner-ontonotes\",\"bert-large-uncased-mix-16-edges-ner-ontonotes\",\"bert-large-uncased-mix-17-edges-ner-ontonotes\",\"bert-large-uncased-mix-18-edges-ner-ontonotes\",\"bert-large-uncased-mix-19-edges-ner-ontonotes\",\"bert-large-uncased-mix-20-edges-ner-ontonotes\",\"bert-large-uncased-mix-21-edges-ner-ontonotes\",\"bert-large-uncased-mix-22-edges-ner-ontonotes\",\"bert-large-uncased-mix-23-edges-ner-ontonotes\",\"bert-large-uncased-mix-24-edges-ner-ontonotes\",\"bert-large-uncased-mix-01-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-02-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-03-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-04-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-05-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-06-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-07-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-08-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-09-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-10-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-11-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-12-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-13-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-14-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-15-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-16-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-17-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-18-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-19-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-20-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-21-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-22-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-23-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-24-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-01-edges-pos-ontonotes\",\"bert-large-uncased-mix-02-edges-pos-ontonotes\",\"bert-large-uncased-mix-03-edges-pos-ontonotes\",\"bert-large-uncased-mix-04-edges-pos-ontonotes\",\"bert-large-uncased-mix-05-edges-pos-ontonotes\",\"bert-large-uncased-mix-06-edges-pos-ontonotes\",\"bert-large-uncased-mix-07-edges-pos-ontonotes\",\"bert-large-uncased-mix-08-edges-pos-ontonotes\",\"bert-large-uncased-mix-09-edges-pos-ontonotes\",\"bert-large-uncased-mix-10-edges-pos-ontonotes\",\"bert-large-uncased-mix-11-edges-pos-ontonotes\",\"bert-large-uncased-mix-12-edges-pos-ontonotes\",\"bert-large-uncased-mix-13-edges-pos-ontonotes\",\"bert-large-uncased-mix-14-edges-pos-ontonotes\",\"bert-large-uncased-mix-15-edges-pos-ontonotes\",\"bert-large-uncased-mix-16-edges-pos-ontonotes\",\"bert-large-uncased-mix-17-edges-pos-ontonotes\",\"bert-large-uncased-mix-18-edges-pos-ontonotes\",\"bert-large-uncased-mix-19-edges-pos-ontonotes\",\"bert-large-uncased-mix-20-edges-pos-ontonotes\",\"bert-large-uncased-mix-21-edges-pos-ontonotes\",\"bert-large-uncased-mix-22-edges-pos-ontonotes\",\"bert-large-uncased-mix-23-edges-pos-ontonotes\",\"bert-large-uncased-mix-24-edges-pos-ontonotes\",\"bert-large-uncased-mix-01-edges-rel-semeval\",\"bert-large-uncased-mix-02-edges-rel-semeval\",\"bert-large-uncased-mix-03-edges-rel-semeval\",\"bert-large-uncased-mix-04-edges-rel-semeval\",\"bert-large-uncased-mix-05-edges-rel-semeval\",\"bert-large-uncased-mix-06-edges-rel-semeval\",\"bert-large-uncased-mix-07-edges-rel-semeval\",\"bert-large-uncased-mix-08-edges-rel-semeval\",\"bert-large-uncased-mix-09-edges-rel-semeval\",\"bert-large-uncased-mix-10-edges-rel-semeval\",\"bert-large-uncased-mix-11-edges-rel-semeval\",\"bert-large-uncased-mix-12-edges-rel-semeval\",\"bert-large-uncased-mix-13-edges-rel-semeval\",\"bert-large-uncased-mix-14-edges-rel-semeval\",\"bert-large-uncased-mix-15-edges-rel-semeval\",\"bert-large-uncased-mix-16-edges-rel-semeval\",\"bert-large-uncased-mix-17-edges-rel-semeval\",\"bert-large-uncased-mix-18-edges-rel-semeval\",\"bert-large-uncased-mix-19-edges-rel-semeval\",\"bert-large-uncased-mix-20-edges-rel-semeval\",\"bert-large-uncased-mix-21-edges-rel-semeval\",\"bert-large-uncased-mix-22-edges-rel-semeval\",\"bert-large-uncased-mix-23-edges-rel-semeval\",\"bert-large-uncased-mix-24-edges-rel-semeval\",\"bert-large-uncased-mix-01-edges-spr1\",\"bert-large-uncased-mix-02-edges-spr1\",\"bert-large-uncased-mix-03-edges-spr1\",\"bert-large-uncased-mix-04-edges-spr1\",\"bert-large-uncased-mix-05-edges-spr1\",\"bert-large-uncased-mix-06-edges-spr1\",\"bert-large-uncased-mix-07-edges-spr1\",\"bert-large-uncased-mix-08-edges-spr1\",\"bert-large-uncased-mix-09-edges-spr1\",\"bert-large-uncased-mix-10-edges-spr1\",\"bert-large-uncased-mix-11-edges-spr1\",\"bert-large-uncased-mix-12-edges-spr1\",\"bert-large-uncased-mix-13-edges-spr1\",\"bert-large-uncased-mix-14-edges-spr1\",\"bert-large-uncased-mix-15-edges-spr1\",\"bert-large-uncased-mix-16-edges-spr1\",\"bert-large-uncased-mix-17-edges-spr1\",\"bert-large-uncased-mix-18-edges-spr1\",\"bert-large-uncased-mix-19-edges-spr1\",\"bert-large-uncased-mix-20-edges-spr1\",\"bert-large-uncased-mix-21-edges-spr1\",\"bert-large-uncased-mix-22-edges-spr1\",\"bert-large-uncased-mix-23-edges-spr1\",\"bert-large-uncased-mix-24-edges-spr1\",\"bert-large-uncased-mix-01-edges-srl-conll2012\",\"bert-large-uncased-mix-02-edges-srl-conll2012\",\"bert-large-uncased-mix-03-edges-srl-conll2012\",\"bert-large-uncased-mix-04-edges-srl-conll2012\",\"bert-large-uncased-mix-05-edges-srl-conll2012\",\"bert-large-uncased-mix-06-edges-srl-conll2012\",\"bert-large-uncased-mix-07-edges-srl-conll2012\",\"bert-large-uncased-mix-08-edges-srl-conll2012\",\"bert-large-uncased-mix-09-edges-srl-conll2012\",\"bert-large-uncased-mix-10-edges-srl-conll2012\",\"bert-large-uncased-mix-11-edges-srl-conll2012\",\"bert-large-uncased-mix-12-edges-srl-conll2012\",\"bert-large-uncased-mix-13-edges-srl-conll2012\",\"bert-large-uncased-mix-14-edges-srl-conll2012\",\"bert-large-uncased-mix-15-edges-srl-conll2012\",\"bert-large-uncased-mix-16-edges-srl-conll2012\",\"bert-large-uncased-mix-17-edges-srl-conll2012\",\"bert-large-uncased-mix-18-edges-srl-conll2012\",\"bert-large-uncased-mix-19-edges-srl-conll2012\",\"bert-large-uncased-mix-20-edges-srl-conll2012\",\"bert-large-uncased-mix-21-edges-srl-conll2012\",\"bert-large-uncased-mix-22-edges-srl-conll2012\",\"bert-large-uncased-mix-23-edges-srl-conll2012\",\"bert-large-uncased-mix-24-edges-srl-conll2012\"],\"exp_type\":[\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\"],\"f1_errn95\":{\"__ndarray__\":\"YbyXW15qhD83mxUglT6EP6TjVjSnIoQ/egk/W3Z+gz+hkn2X90+DPyGni5UxWYM/yDjWnvkigz+3V8b+XrCCP6sQ/SP1jII/tCQwnJgigj/E279c13yBP5MZxbC0cYE/6sViBDS9gD838IN551WAP96jb/mnKn8/Hlst8aiHfj8qbxpEFZl9Pz6hqemOonw/JDrU/oORfD/Z/zWnZvd8P6l5aKu4qXw/envGuChifD8An6bUVHF8P1xVcqClrnw/tfFHZpDvbz/efdJWmvluP8eWhMMOE24/HvVgdf+taz+ODjvul0RrP13RAjFaUms/uUE5MPHHaj9L7gKADpNqP3zY2gYzO2o/Wb1i+KQhaT8HXFxs5qdnP2usiuD8kWY/ugMy7vbXZT993WUhUA9lPx2EYV40J2U/FAU5yduhZD+sORxUwNZkPz3L9Yvo12Q/K7Gh7Z5rZD8A1qMTTYpkP8fHKEvidGQ/x2OT5b6uZD8FxZbPv8ZkP7vF21h/t2Q/NWaSgEXoaz9ZcqU5MP9rP6PZpqtbqWs/XEIZJPnKaj/uNZ+jiJBpP2BMDpcGo2k/3kr9uNkdaT+dUvQ8p+RoP85V7qKym2g/5I/0fXhXaD/N3PyrYk1nPyStC2aVJGc/oc0iBcejZj/eomBdBWJmP2A+xYlP12U/2WmTH9VDZT9ydYJq7mtlPwf+fg6hJGU/2x97mc0FZT/Q30HLnxBlP1O41pD/UmU/iCg0REgIZT9cLItEVBBlPxKAthfSa2U/XoZcAwvlWT9bPWy9iVJZP5NlQfwmF1k/1wH9MbuUVz8G1u7Qcz1XP1nEpmsOMlc/ZSDnr+xVVz/isiZ5oBtXP4egxcw/3FY/YDqjA+NVVj+j6P6e19ZVPzDi4QGxWlU/1mnvGzyIVT/8ShLO6ZpVP9xVbObFjVU//Us4IuxKVT/z7w+vmKRVP5cQCQ0qM1U/xEV7AE1OVT+OZxf/3DxVP3kXTERpkFU/Nx6MMCGjVT+p3MJf5YRVPyN56PwneVU/+CmZCEh/UD8hnKjZ9gpOP0NeIxzd4Uw/UVqDBdaeSj+Lgvvu4aRJPwrC/XeAGUk/JgFo5SdRSD9crpyUHeBHP+iwPIGCsEc/Lwr3kscoRz+u1YvdRD1GP8Q+t2Q4hkU/eiAqREHlRD+Q8tGpj/hEP6oFeIpFUkU/JefzlmsIRT9ubzk+tlFFP2bprwPUP0U/Qy3TCsgQRT9KF6vRNDtFPye6bh1qPEU/YfxrBV9FRT/YhRjvI01FP8QXNK3PU0U/imG10137nz96kvjPZhyfP8yWEBieiJ8/pTsu6p7Xnj+eSWPUyjSeP4o/3vicnZ0/0datB50qnT/j9Cvee+WcPxp6H94FrZw/EjSnb5ZinD+ZS7M5jeabP4XSXDXaPJs/Q52zr4rpmj+zaLb5yfKaP3RMtsbII5o/T5Iw3X9bmT/Ac3SfzKCYP/d4duaHqZg/poHpxxppmD9h+inv+vSXP7qblP7a/pc/8BgtthpGlz8kezGKqnCXPwW/sJsZ/ZY/7W0xEZqbhT8Jc1OB5Y2FP5dglwYdboU/VKW5C7cchT/QS6HKlgeFP4EAQseH64Q/xqKeaGn1hD/Le9wM386EP4hZQX5uqoQ//z0HB4F+hD8b7to5GT+EPx+Vy6HuJIQ/1RAg00EzhD8lxTI/QhuEP65+bv7A/oM/7tduyPSmgz8LN5e5xaWDP82jC/M+jYM/uc6VpH1+gz99De5zSG2DPxCoS8MDL4M/E2iWicM1gz/PPP0+6SqDP/MYEB3iHIM/NKFILzC2ZT/k1Lcy/O9jP6GBP09Q4WQ/8l/Ksms5Yz+IX9oC2ihjP7W3Vg0yGmM/lHhnMnmfYj/tf9F0kd1hP1D/HSqoJmI/uF3kgVuQYT+QyCwFtMNgP5z3hw9NjGA/hpLc09P5Xz8OPavsFF9fP4ag8vb2ZF8//8zuSkb2Xj/p+iz9vzZfP+22DrTqmV8/D9xeIdUxXz9sHOBcjM1eP0MslZLV514/MZ7JVSQqXz9pAChUcvVeP+P36luDMV8/\",\"dtype\":\"float64\",\"shape\":[192]},\"f1_score\":{\"__ndarray__\":\"p0NJbJox6j+9Z07rtVfqP1PseqgNaOo/HKZ+X1TS6j+MMJnNS+/qP0WrgUxD7Oo/GzbqltcL6z9dxYU7VkrrP4nsI+WSZOs/ndvXyIyc6z84W0n2ufLrP818ndEd/+s/Lm/Z0uZU7D8TL3K6xIvsP1nqigaL5ew/YRWK2c4J7T/aLhLiRD7tP0IvuJm0b+0/H2sgaJVw7T8VIb1lCF3tPxNyKuAXbu0/1Ekl11957T/yp2OHCXjtP1qcpWasa+0/+66CKpE47D/OCkjTxH7sPx+0+9SQuOw/QcBYKVBK7T9A2Z086WHtP54aNGcGW+0/lbI8rzh37T8PQF+mXoPtP1FcA17Qk+0/+7mdAvXM7T9HDi4SvRTuP0z8coaBR+4/2PVjVzJj7j+pYfLAnoLuP8sV6hm6fu4/zWRoVgeT7j/rLb5I8ozuP/axCNkujO4//xwAuXqa7j/UF1O/h5fuPwwD9TIfmu4/H5iM7i2T7j9eHu97FI/uP5XlmwrXkO4/DXFB5fre7T82R3GCVdrtP/ZxHFZY6u0/isgy5aoN7j8QCKf1kz3uPwoME9ztOu4/ZPhQRlFN7j9hgf95Q1XuP2r6c7iVXe4/GuE+1WBo7j/wdEmnh4zuP8FSk6WFkO4/reHvIhig7j/rLOjDTaruP7eTG2l6u+4/BgKQQj7M7j8rpCc7kcbuP1j77fHqz+4/dwajPpvT7j9+rDobZ9HuP90+iqopye4/UhgAk3bR7j8osd/uL9DuP4+pfJEmxO4/iwDrqaRw6T8CrKgDJ8vpPyWIfP148ek/etiwH3/O6j9m9LgWRvzqPy+3YkriAes/ExFHO6Xv6j8sCuXlKg3rP8fZZhpRK+s/OF7wNOVq6z8LsGv9E6XrP1O3oDFM0+s/pNTigxXK6z9+JtZlAsPrP72gAcyiy+s/6KMAT6Dl6z/h0C3D2rzrP6kduaWP6+s/5qp22xfi6z+Revg2u+nrPx3Y7gn1yes//BLRWE276z/DJEODp8vrPzr9rOWW0+s/OKTj0M9U7T+Hc48vaNHtP1pwwwHQ/u0/wmrxj0JR7j+2zdv803HuP1ILmCxAg+4/z6a8bfGb7j9hovBMZqnuP43C6SP8ru4/g1JfSnK+7j+xM0FHW9juP0a6Kji36+4/qrJL/Fv87j90IRCUSfruPxtY3gjd8O4/6hHXqq347j81+ZkZPvHuP0adVA8B8+4/7EckneL37j/SoX+TdvPuP0ofe0xf8+4/VEJbCWXy7j+y/pqJtPHuP9Yv5qwS8e4/RB64inam5D/kE4ucSPHkP2CNifRA5eQ/VM/hHaHL5T9dFh3O0gzmPzIdYcRBquY/WI4aV44a5z8RBNev21rnP35OWMM7o+c/V3zFV3zF5z9yr4JZUg7oP8nSDmTjfug/PIjvIL6D6D8RdVqXAK/oPwxmmqRNEek/aF4Pu/qT6T8R1bg2ePrpP7To+AhyDOo/V7PzVKlQ6j/bALa3I5PqP8uU4icboOo/Te07F+Tq6j9ydGiSf8HqP/4H5GEp7+o/Ia/yfEj/6D+yNzNpCxzpP1nPMVnPMek/WhfImXdk6T881z1JvHPpP11xo29niuk/enYyLbma6T97sK3p37HpP2A/NNsS0Ok/R2io9y/s6T+HwMtW1/bpP5YWcTCDI+o/BhLgnC8h6j8/OExvVTfqP+4MxCOdSeo/Xtk3mml46j/sDcK2jYjqP7V/8pJnnOo/7z7cAgqj6j/Ib9P/57LqP+YvM6Jkzeo/ou6sGerO6j/+lI1M9drqP/nCVgpjyuo/DpL7WS0r6j9Km3635DXrPx8ADkkWpuo/uGT8L9eR6z8ZCKtQ957rP2DfQLs7pes/EJ5d+UDp6z9iaBgf+EnsP/42oKxqJew/UkIFq5lp7D9L1QsJK8vsPwLH61sY1+w/mD4bfJUY7T+uVPHwSTrtP7CZY81SN+0/tytSaoVQ7T8HuM7CjUTtP8X9eIb1Mu0/P1o1p45D7T+QbcEEyFXtP7CAQse8Ve0/ANgXt09E7T99yFW4IFPtP1P0yyhPQ+0/\",\"dtype\":\"float64\",\"shape\":[192]},\"fn_count\":{\"__ndarray__\":\"AAAAAACEkUAAAAAAAACSQAAAAAAAQJFAAAAAAABQj0AAAAAAAHiOQAAAAAAAOI9AAAAAAADYjUAAAAAAACiLQAAAAAAAUItAAAAAAAAgiUAAAAAAAHiGQAAAAAAAAIdAAAAAAAAYhEAAAAAAAGCDQAAAAAAAeIFAAAAAAADAgEAAAAAAADCAQAAAAAAAQH5AAAAAAACwfEAAAAAAANB9QAAAAAAAEH5AAAAAAAAgfEAAAAAAAOB8QAAAAAAAQH1AAAAAAACKrkAAAAAAAAKsQAAAAAAAIKpAAAAAAAAypUAAAAAAAGKkQAAAAAAA0KRAAAAAAAD0o0AAAAAAAICjQAAAAAAADKNAAAAAAAAeoUAAAAAAAFydQAAAAAAAsJlAAAAAAABImEAAAAAAAESWQAAAAAAAjJZAAAAAAAA8lUAAAAAAAFiVQAAAAAAAfJVAAAAAAADYlEAAAAAAAMyUQAAAAAAAuJRAAAAAAADolEAAAAAAAECVQAAAAAAAOJVAAAAAAAC0mEAAAAAAABSZQAAAAAAA9JdAAAAAAABIlkAAAAAAAPCTQAAAAAAADJRAAAAAAABkk0AAAAAAABCTQAAAAAAACJNAAAAAAABMkkAAAAAAAIyQQAAAAAAAnJBAAAAAAAAMkEAAAAAAAHiOQAAAAAAA2IxAAAAAAACgi0AAAAAAAHiMQAAAAAAASItAAAAAAADoikAAAAAAAHCLQAAAAAAAWIxAAAAAAAC4i0AAAAAAAPCLQAAAAAAAaI1AAAAAAOCw7kAAAAAAgP7sQAAAAACg+etAAAAAAIDv5kAAAAAA4NDlQAAAAACg7uVAAAAAACD55UAAAAAAYCDlQAAAAADAHeRAAAAAAICh4kAAAAAAIGbhQAAAAABAet9AAAAAAMDg4EAAAAAAoC/hQAAAAADgl+FAAAAAAMBp4EAAAAAAgBDhQAAAAABArd9AAAAAAGA+4EAAAAAAYBrgQAAAAABgeeFAAAAAACDa4EAAAAAAwNvgQAAAAACAHuFAAAAAAMAK2kAAAAAAwHHVQAAAAAAAkdNAAAAAAADhz0AAAAAAAHfNQAAAAAAASMxAAAAAAIAbykAAAAAAgPnIQAAAAACAfMhAAAAAAIB1x0AAAAAAgKLFQAAAAAAAMsRAAAAAAICJwkAAAAAAAP7CQAAAAAAADMRAAAAAAAAgw0AAAAAAgKDDQAAAAAAAm8NAAAAAAAAYw0AAAAAAAJfDQAAAAAAAjcNAAAAAAAC1w0AAAAAAgJrDQAAAAACAjcNAAAAAAABQe0AAAAAAALB7QAAAAAAAQHtAAAAAAACweEAAAAAAANB4QAAAAAAAMHdAAAAAAAAAdkAAAAAAAFB1QAAAAAAAUHRAAAAAAABAdEAAAAAAAMBzQAAAAAAAwHJAAAAAAAAgc0AAAAAAAFByQAAAAAAAsHFAAAAAAABgcEAAAAAAAOBuQAAAAAAAIG5AAAAAAAAgbEAAAAAAAMBqQAAAAAAAAGpAAAAAAAAgaUAAAAAAAGBqQAAAAAAAwGlAAAAAAAAslUAAAAAAAJSVQAAAAAAADJVAAAAAAACwk0AAAAAAAGyTQAAAAAAAJJNAAAAAAAAolEAAAAAAAGyTQAAAAAAALJNAAAAAAACEkkAAAAAAAOiQQAAAAAAASJFAAAAAAAC0kUAAAAAAALSRQAAAAAAAWJFAAAAAAAAEkEAAAAAAAJyQQAAAAAAAmJBAAAAAAABEkEAAAAAAAGiQQAAAAAAASI5AAAAAAADgjkAAAAAAADiPQAAAAAAAGI1AAAAAAABZ0kAAAAAAgEDOQAAAAADABNFAAAAAAAA5zEAAAAAAALXLQAAAAACAm8tAAAAAAACnyUAAAAAAABTHQAAAAAAAF8hAAAAAAIB6xkAAAAAAAKvDQAAAAAAA7sNAAAAAAAD5wUAAAAAAAPbAQAAAAAAAIsFAAAAAAABKwEAAAAAAgJDAQAAAAAAA58BAAAAAAICzwEAAAAAAgEzAQAAAAAAAAsBAAAAAAAC5wEAAAAAAABPAQAAAAACAucBA\",\"dtype\":\"float64\",\"shape\":[192]},\"fp_count\":{\"__ndarray__\":\"AAAAAADgjUAAAAAAAHiKQAAAAAAAwItAAAAAAACoikAAAAAAAFCKQAAAAAAAcIlAAAAAAACwiUAAAAAAABiKQAAAAAAAiIhAAAAAAACQiEAAAAAAAKCHQAAAAAAAUIZAAAAAAACwhUAAAAAAANiDQAAAAAAAwIFAAAAAAADYgEAAAAAAAPB9QAAAAAAAsHtAAAAAAABwfUAAAAAAAAB+QAAAAAAAEHxAAAAAAABAfUAAAAAAAIB8QAAAAAAAQH1AAAAAAACkm0AAAAAAALiaQAAAAAAAaJlAAAAAAABclkAAAAAAAOCVQAAAAAAAkJVAAAAAAAC4lEAAAAAAAIyUQAAAAAAA8JNAAAAAAACgkkAAAAAAAPSQQAAAAAAA+I9AAAAAAACQjUAAAAAAAMCLQAAAAAAA6ItAAAAAAADAikAAAAAAALiLQAAAAAAAkItAAAAAAAAgikAAAAAAANCKQAAAAAAAeIpAAAAAAABwi0AAAAAAAICLQAAAAAAAOItAAAAAAAAckUAAAAAAABCRQAAAAAAACJFAAAAAAAAIkEAAAAAAAICNQAAAAAAAsI1AAAAAAAAojEAAAAAAAJiLQAAAAAAAUIpAAAAAAAAwikAAAAAAADCIQAAAAAAAaIdAAAAAAAAghkAAAAAAAECGQAAAAAAAQIVAAAAAAADgg0AAAAAAAOCDQAAAAAAAqINAAAAAAAB4g0AAAAAAAECDQAAAAAAAmINAAAAAAADwgkAAAAAAAOiCQAAAAAAAQINAAAAAAGC64UAAAAAAAAHhQAAAAABgIeFAAAAAAIBy4EAAAAAAAGDgQAAAAACgBOBAAAAAAOCa4EAAAAAA4LjgQAAAAADgB+FAAAAAAKDI4EAAAAAA4F7gQAAAAABA6+BAAAAAAICE30AAAAAAADXfQAAAAADAi91AAAAAAMDO3kAAAAAAQPTfQAAAAACA4d9AAAAAAAB+30AAAAAAAFPfQAAAAAAA+d1AAAAAACBP4EAAAAAAgHXfQAAAAACAOt5AAAAAAIDB1EAAAAAAAN7QQAAAAAAAWc9AAAAAAIB0y0AAAAAAgGbJQAAAAACALshAAAAAAAD/xkAAAAAAgErGQAAAAACABMZAAAAAAIDoxEAAAAAAACnDQAAAAACA78FAAAAAAIBUwUAAAAAAACTBQAAAAAAAXMFAAAAAAIA6wUAAAAAAAMHBQAAAAACAhsFAAAAAAABgwUAAAAAAAHrBQAAAAAAAiMFAAAAAAACBwUAAAAAAgLbBQAAAAACA28FAAAAAAABgYUAAAAAAAABaQAAAAAAAgF5AAAAAAADgYEAAAAAAAABcQAAAAAAAwFxAAAAAAABAXUAAAAAAAIBdQAAAAAAAQF9AAAAAAABAXUAAAAAAAIBbQAAAAAAAQFpAAAAAAACAV0AAAAAAAMBZQAAAAAAAAFdAAAAAAABAVkAAAAAAAABVQAAAAAAAAFZAAAAAAABAV0AAAAAAAMBWQAAAAAAAAFhAAAAAAACAVUAAAAAAAMBUQAAAAAAAgFNAAAAAAAAgk0AAAAAAAKyRQAAAAAAA4JFAAAAAAACEkkAAAAAAAHySQAAAAAAARJJAAAAAAABIkEAAAAAAALyQQAAAAAAARJBAAAAAAAB0kEAAAAAAAISSQAAAAAAAuJBAAAAAAAAskEAAAAAAACCPQAAAAAAAKI9AAAAAAAAwkEAAAAAAANCNQAAAAAAAyIxAAAAAAABYjUAAAAAAABiMQAAAAAAAMI5AAAAAAABIjUAAAAAAACiMQAAAAAAAAJBAAAAAAABywUAAAAAAAJC9QAAAAAAAo79AAAAAAAAWu0AAAAAAAFO7QAAAAAAADbtAAAAAAABaukAAAAAAALy4QAAAAAAAQrlAAAAAAACUt0AAAAAAAFy2QAAAAAAAurRAAAAAAAAHtEAAAAAAAKizQAAAAAAAfrNAAAAAAABqs0AAAAAAAMCzQAAAAAAAZ7RAAAAAAACCs0AAAAAAAPWyQAAAAAAAprNAAAAAAABls0AAAAAAALWzQAAAAAAAebNA\",\"dtype\":\"float64\",\"shape\":[192]},\"headroom_frac\":[0.11924885819738537,0.03996721039058294,0.017140421649633177,0.11146254929550593,0.03038005576537206,-0.0031810205357324533,0.03312049975352221,0.06554423838211923,0.02751723148026277,0.05870779732206643,0.09038194987617033,0.012994533931393479,0.0899711835062617,0.057544055426013214,0.0941554286364117,0.038034739061359575,0.05502101674630216,0.05184888037111926,0.0009209019126946332,-0.02050474977806233,0.017893088720822545,0.011831623054286953,-0.001402548109784854,-0.012967003881791192,0.2552961451987966,0.08571666388070989,0.07056984300753828,0.17795750809220312,0.028813297520848605,-0.008407960805112571,0.03442798399467113,0.014833374333912536,0.02007851533913474,0.06977179598644982,0.08764532430371803,0.06198679296932539,0.033810481044065,0.038367950323117364,-0.004753551766156646,0.0247882900172759,-0.007426600182279491,-0.00093197779573694,0.017455773577464858,-0.0036010119373959273,0.003164343846574142,-0.008476982213772787,-0.005005107139037365,0.002148873429032305,0.4791982211336487,-0.009891106145895561,0.0340871052865562,0.07520020654437398,0.10199998036717652,-0.005639610582429029,0.03914809319882639,0.016917214660451055,0.0177155281538795,0.02297859496756056,0.07696540660112836,0.008499427846274655,0.033152979036450446,0.02173578613491763,0.036563897265948664,0.035692553434345645,-0.012083724412743479,0.019906658225229384,0.007852611018777643,-0.004691581164156769,-0.01754286793889932,0.017671690507210475,-0.0027168640452855117,-0.02562503503298699,0.43393080373117005,0.08069473862517886,0.034164924189038576,0.19705666713813655,0.04081324252297465,0.005001685717589329,-0.01626063414168284,0.026320767613806483,0.026880014569003505,0.05668416484190521,0.05187341178951657,0.041207585195417534,-0.008214686744818612,-0.006307464967222522,0.007691196972660172,0.02317212566698648,-0.03635028836649214,0.04164188588817257,-0.008441174648693595,0.0068097961739946354,-0.028328744863199494,-0.013065756438097056,0.014578921690911177,0.007074678879016351,0.3784284742308631,0.1828476667355257,0.0666346555308144,0.12099473483139221,0.04779518822915531,0.025568237353502887,0.03623728251225715,0.01974825874378391,0.008196938642824872,0.022690440103526475,0.03802426441659814,0.028410415478405303,0.024424942293711224,-0.0030406763304073217,-0.013830330429953717,0.01146895508684831,-0.010912080276386219,0.0025850134239233467,0.007163492216400578,-0.006489543235589698,-0.0001337192172299884,-0.001434364809713496,-0.0010115825845617107,-0.0009276700694607807,0.16221498189598205,0.03896546992230503,-0.006265014174623446,0.11997591758797638,0.03395204362609319,0.08198897667938805,0.058483648736245904,0.033487470970807134,0.037692043645149255,0.01783806788879979,0.03793176021336738,0.05862284787089483,0.002528150688210505,0.0225289374879972,0.0511935388585347,0.06805410860647258,0.05337522991053467,0.00936147400547985,0.03552589384242925,0.03462064620541661,0.0067527124357650865,0.03894686462089184,-0.021556712297086854,0.023780632679324145,0.07247782669231503,0.056082018969539724,0.04244075766653939,0.09877673197230072,0.02977159547370385,0.04420186458920255,0.03182159173573683,0.04514331750093816,0.058885546990404526,0.05481900795319719,0.020773669739524464,0.08710461877813493,-0.0045368655638756035,0.043185960148158196,0.0356449582877082,0.09125322407314639,0.0314734063674154,0.03870737444621078,0.012936313692669019,0.030939546172008905,0.05164691316155298,0.002966565950091014,0.023484003296992732,-0.03231217680545297,0.04427504907852022,0.3144658977427871,-0.1695519225694335,0.2779602169777315,0.015475620765603718,0.007388990299869476,0.08019797792426021,0.11403008811614881,-0.04309647767899822,0.08039057846486555,0.11503543473906527,0.01406248617789181,0.07721303638837286,0.03973896689669341,-0.0034965449250411143,0.0297090482565448,-0.014109716236869104,-0.020744562443314917,0.01956981024831055,0.021486838349607178,-5.168215563501218e-05,-0.020545647839889162,0.017468822980427713,-0.018650709311520762],\"index\":[14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417],\"kl_unif\":{\"__ndarray__\":\"smln+9gk4z+yaWf72CTjP7JpZ/vYJOM/smln+9gk4z+yaWf72CTjP7JpZ/vYJOM/smln+9gk4z+yaWf72CTjP7JpZ/vYJOM/smln+9gk4z+yaWf72CTjP7JpZ/vYJOM/smln+9gk4z+yaWf72CTjP7JpZ/vYJOM/smln+9gk4z+yaWf72CTjP7JpZ/vYJOM/smln+9gk4z+yaWf72CTjP7JpZ/vYJOM/smln+9gk4z+yaWf72CTjP7JpZ/vYJOM/U3dL5sBn8j9Td0vmwGfyP1N3S+bAZ/I/U3dL5sBn8j9Td0vmwGfyP1N3S+bAZ/I/U3dL5sBn8j9Td0vmwGfyP1N3S+bAZ/I/U3dL5sBn8j9Td0vmwGfyP1N3S+bAZ/I/U3dL5sBn8j9Td0vmwGfyP1N3S+bAZ/I/U3dL5sBn8j9Td0vmwGfyP1N3S+bAZ/I/U3dL5sBn8j9Td0vmwGfyP1N3S+bAZ/I/U3dL5sBn8j9Td0vmwGfyP1N3S+bAZ/I/KvtYfCS7+T8q+1h8JLv5Pyr7WHwku/k/KvtYfCS7+T8q+1h8JLv5Pyr7WHwku/k/KvtYfCS7+T8q+1h8JLv5Pyr7WHwku/k/KvtYfCS7+T8q+1h8JLv5Pyr7WHwku/k/KvtYfCS7+T8q+1h8JLv5Pyr7WHwku/k/KvtYfCS7+T8q+1h8JLv5Pyr7WHwku/k/KvtYfCS7+T8q+1h8JLv5Pyr7WHwku/k/KvtYfCS7+T8q+1h8JLv5Pyr7WHwku/k/1wcJs1Mx+T/XBwmzUzH5P9cHCbNTMfk/1wcJs1Mx+T/XBwmzUzH5P9cHCbNTMfk/1wcJs1Mx+T/XBwmzUzH5P9cHCbNTMfk/1wcJs1Mx+T/XBwmzUzH5P9cHCbNTMfk/1wcJs1Mx+T/XBwmzUzH5P9cHCbNTMfk/1wcJs1Mx+T/XBwmzUzH5P9cHCbNTMfk/1wcJs1Mx+T/XBwmzUzH5P9cHCbNTMfk/1wcJs1Mx+T/XBwmzUzH5P9cHCbNTMfk/PGxpRu6G+T88bGlG7ob5PzxsaUbuhvk/PGxpRu6G+T88bGlG7ob5PzxsaUbuhvk/PGxpRu6G+T88bGlG7ob5PzxsaUbuhvk/PGxpRu6G+T88bGlG7ob5PzxsaUbuhvk/PGxpRu6G+T88bGlG7ob5PzxsaUbuhvk/PGxpRu6G+T88bGlG7ob5PzxsaUbuhvk/PGxpRu6G+T88bGlG7ob5PzxsaUbuhvk/PGxpRu6G+T88bGlG7ob5PzxsaUbuhvk/IbZb25sJ4D8htlvbmwngPyG2W9ubCeA/IbZb25sJ4D8htlvbmwngPyG2W9ubCeA/IbZb25sJ4D8htlvbmwngPyG2W9ubCeA/IbZb25sJ4D8htlvbmwngPyG2W9ubCeA/IbZb25sJ4D8htlvbmwngPyG2W9ubCeA/IbZb25sJ4D8htlvbmwngPyG2W9ubCeA/IbZb25sJ4D8htlvbmwngPyG2W9ubCeA/IbZb25sJ4D8htlvbmwngPyG2W9ubCeA/Zn7/NR5c1T9mfv81HlzVP2Z+/zUeXNU/Zn7/NR5c1T9mfv81HlzVP2Z+/zUeXNU/Zn7/NR5c1T9mfv81HlzVP2Z+/zUeXNU/Zn7/NR5c1T9mfv81HlzVP2Z+/zUeXNU/Zn7/NR5c1T9mfv81HlzVP2Z+/zUeXNU/Zn7/NR5c1T9mfv81HlzVP2Z+/zUeXNU/Zn7/NR5c1T9mfv81HlzVP2Z+/zUeXNU/Zn7/NR5c1T9mfv81HlzVP2Z+/zUeXNU/3Qo2TbTp9D/dCjZNtOn0P90KNk206fQ/3Qo2TbTp9D/dCjZNtOn0P90KNk206fQ/3Qo2TbTp9D/dCjZNtOn0P90KNk206fQ/3Qo2TbTp9D/dCjZNtOn0P90KNk206fQ/3Qo2TbTp9D/dCjZNtOn0P90KNk206fQ/3Qo2TbTp9D/dCjZNtOn0P90KNk206fQ/3Qo2TbTp9D/dCjZNtOn0P90KNk206fQ/3Qo2TbTp9D/dCjZNtOn0P90KNk206fQ/\",\"dtype\":\"float64\",\"shape\":[192]},\"label\":[\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\"],\"layer_num\":[\"01\",\"02\",\"03\",\"04\",\"05\",\"06\",\"07\",\"08\",\"09\",\"10\",\"11\",\"12\",\"13\",\"14\",\"15\",\"16\",\"17\",\"18\",\"19\",\"20\",\"21\",\"22\",\"23\",\"24\",\"01\",\"02\",\"03\",\"04\",\"05\",\"06\",\"07\",\"08\",\"09\",\"10\",\"11\",\"12\",\"13\",\"14\",\"15\",\"16\",\"17\",\"18\",\"19\",\"20\",\"21\",\"22\",\"23\",\"24\",\"01\",\"02\",\"03\",\"04\",\"05\",\"06\",\"07\",\"08\",\"09\",\"10\",\"11\",\"12\",\"13\",\"14\",\"15\",\"16\",\"17\",\"18\",\"19\",\"20\",\"21\",\"22\",\"23\",\"24\",\"01\",\"02\",\"03\",\"04\",\"05\",\"06\",\"07\",\"08\",\"09\",\"10\",\"11\",\"12\",\"13\",\"14\",\"15\",\"16\",\"17\",\"18\",\"19\",\"20\",\"21\",\"22\",\"23\",\"24\",\"01\",\"02\",\"03\",\"04\",\"05\",\"06\",\"07\",\"08\",\"09\",\"10\",\"11\",\"12\",\"13\",\"14\",\"15\",\"16\",\"17\",\"18\",\"19\",\"20\",\"21\",\"22\",\"23\",\"24\",\"01\",\"02\",\"03\",\"04\",\"05\",\"06\",\"07\",\"08\",\"09\",\"10\",\"11\",\"12\",\"13\",\"14\",\"15\",\"16\",\"17\",\"18\",\"19\",\"20\",\"21\",\"22\",\"23\",\"24\",\"01\",\"02\",\"03\",\"04\",\"05\",\"06\",\"07\",\"08\",\"09\",\"10\",\"11\",\"12\",\"13\",\"14\",\"15\",\"16\",\"17\",\"18\",\"19\",\"20\",\"21\",\"22\",\"23\",\"24\",\"01\",\"02\",\"03\",\"04\",\"05\",\"06\",\"07\",\"08\",\"09\",\"10\",\"11\",\"12\",\"13\",\"14\",\"15\",\"16\",\"17\",\"18\",\"19\",\"20\",\"21\",\"22\",\"23\",\"24\"],\"lex_score\":[0.804675649147854,0.804675649147854,0.804675649147854,0.804675649147854,0.804675649147854,0.804675649147854,0.804675649147854,0.804675649147854,0.804675649147854,0.804675649147854,0.804675649147854,0.804675649147854,0.804675649147854,0.804675649147854,0.804675649147854,0.804675649147854,0.804675649147854,0.804675649147854,0.804675649147854,0.804675649147854,0.804675649147854,0.804675649147854,0.804675649147854,0.804675649147854,0.8563817514420556,0.8563817514420556,0.8563817514420556,0.8563817514420556,0.8563817514420556,0.8563817514420556,0.8563817514420556,0.8563817514420556,0.8563817514420556,0.8563817514420556,0.8563817514420556,0.8563817514420556,0.8563817514420556,0.8563817514420556,0.8563817514420556,0.8563817514420556,0.8563817514420556,0.8563817514420556,0.8563817514420556,0.8563817514420556,0.8563817514420556,0.8563817514420556,0.8563817514420556,0.8563817514420556,0.905993125093409,0.905993125093409,0.905993125093409,0.905993125093409,0.905993125093409,0.905993125093409,0.905993125093409,0.905993125093409,0.905993125093409,0.905993125093409,0.905993125093409,0.905993125093409,0.905993125093409,0.905993125093409,0.905993125093409,0.905993125093409,0.905993125093409,0.905993125093409,0.905993125093409,0.905993125093409,0.905993125093409,0.905993125093409,0.905993125093409,0.905993125093409,0.7355877588962386,0.7355877588962386,0.7355877588962386,0.7355877588962386,0.7355877588962386,0.7355877588962386,0.7355877588962386,0.7355877588962386,0.7355877588962386,0.7355877588962386,0.7355877588962386,0.7355877588962386,0.7355877588962386,0.7355877588962386,0.7355877588962386,0.7355877588962386,0.7355877588962386,0.7355877588962386,0.7355877588962386,0.7355877588962386,0.7355877588962386,0.7355877588962386,0.7355877588962386,0.7355877588962386,0.8851251582672498,0.8851251582672498,0.8851251582672498,0.8851251582672498,0.8851251582672498,0.8851251582672498,0.8851251582672498,0.8851251582672498,0.8851251582672498,0.8851251582672498,0.8851251582672498,0.8851251582672498,0.8851251582672498,0.8851251582672498,0.8851251582672498,0.8851251582672498,0.8851251582672498,0.8851251582672498,0.8851251582672498,0.8851251582672498,0.8851251582672498,0.8851251582672498,0.8851251582672498,0.8851251582672498,0.6072974644403215,0.6072974644403215,0.6072974644403215,0.6072974644403215,0.6072974644403215,0.6072974644403215,0.6072974644403215,0.6072974644403215,0.6072974644403215,0.6072974644403215,0.6072974644403215,0.6072974644403215,0.6072974644403215,0.6072974644403215,0.6072974644403215,0.6072974644403215,0.6072974644403215,0.6072974644403215,0.6072974644403215,0.6072974644403215,0.6072974644403215,0.6072974644403215,0.6072974644403215,0.6072974644403215,0.7766251728907331,0.7766251728907331,0.7766251728907331,0.7766251728907331,0.7766251728907331,0.7766251728907331,0.7766251728907331,0.7766251728907331,0.7766251728907331,0.7766251728907331,0.7766251728907331,0.7766251728907331,0.7766251728907331,0.7766251728907331,0.7766251728907331,0.7766251728907331,0.7766251728907331,0.7766251728907331,0.7766251728907331,0.7766251728907331,0.7766251728907331,0.7766251728907331,0.7766251728907331,0.7766251728907331,0.8131866690279881,0.8131866690279881,0.8131866690279881,0.8131866690279881,0.8131866690279881,0.8131866690279881,0.8131866690279881,0.8131866690279881,0.8131866690279881,0.8131866690279881,0.8131866690279881,0.8131866690279881,0.8131866690279881,0.8131866690279881,0.8131866690279881,0.8131866690279881,0.8131866690279881,0.8131866690279881,0.8131866690279881,0.8131866690279881,0.8131866690279881,0.8131866690279881,0.8131866690279881,0.8131866690279881],\"max_layer_score\":[0.9210662080825451,0.9210662080825451,0.9210662080825451,0.9210662080825451,0.9210662080825451,0.9210662080825451,0.9210662080825451,0.9210662080825451,0.9210662080825451,0.9210662080825451,0.9210662080825451,0.9210662080825451,0.9210662080825451,0.9210662080825451,0.9210662080825451,0.9210662080825451,0.9210662080825451,0.9210662080825451,0.9210662080825451,0.9210662080825451,0.9210662080825451,0.9210662080825451,0.9210662080825451,0.9210662080825451,0.9563573468484775,0.9563573468484775,0.9563573468484775,0.9563573468484775,0.9563573468484775,0.9563573468484775,0.9563573468484775,0.9563573468484775,0.9563573468484775,0.9563573468484775,0.9563573468484775,0.9563573468484775,0.9563573468484775,0.9563573468484775,0.9563573468484775,0.9563573468484775,0.9563573468484775,0.9563573468484775,0.9563573468484775,0.9563573468484775,0.9563573468484775,0.9563573468484775,0.9563573468484775,0.9563573468484775,0.9633308623671856,0.9633308623671856,0.9633308623671856,0.9633308623671856,0.9633308623671856,0.9633308623671856,0.9633308623671856,0.9633308623671856,0.9633308623671856,0.9633308623671856,0.9633308623671856,0.9633308623671856,0.9633308623671856,0.9633308623671856,0.9633308623671856,0.9633308623671856,0.9633308623671856,0.9633308623671856,0.9633308623671856,0.9633308623671856,0.9633308623671856,0.9633308623671856,0.9633308623671856,0.9633308623671856,0.8725050198344678,0.8725050198344678,0.8725050198344678,0.8725050198344678,0.8725050198344678,0.8725050198344678,0.8725050198344678,0.8725050198344678,0.8725050198344678,0.8725050198344678,0.8725050198344678,0.8725050198344678,0.8725050198344678,0.8725050198344678,0.8725050198344678,0.8725050198344678,0.8725050198344678,0.8725050198344678,0.8725050198344678,0.8725050198344678,0.8725050198344678,0.8725050198344678,0.8725050198344678,0.8725050198344678,0.9683055808687488,0.9683055808687488,0.9683055808687488,0.9683055808687488,0.9683055808687488,0.9683055808687488,0.9683055808687488,0.9683055808687488,0.9683055808687488,0.9683055808687488,0.9683055808687488,0.9683055808687488,0.9683055808687488,0.9683055808687488,0.9683055808687488,0.9683055808687488,0.9683055808687488,0.9683055808687488,0.9683055808687488,0.9683055808687488,0.9683055808687488,0.9683055808687488,0.9683055808687488,0.9683055808687488,0.8416945373467113,0.8416945373467113,0.8416945373467113,0.8416945373467113,0.8416945373467113,0.8416945373467113,0.8416945373467113,0.8416945373467113,0.8416945373467113,0.8416945373467113,0.8416945373467113,0.8416945373467113,0.8416945373467113,0.8416945373467113,0.8416945373467113,0.8416945373467113,0.8416945373467113,0.8416945373467113,0.8416945373467113,0.8416945373467113,0.8416945373467113,0.8416945373467113,0.8416945373467113,0.8416945373467113,0.8392282958199357,0.8392282958199357,0.8392282958199357,0.8392282958199357,0.8392282958199357,0.8392282958199357,0.8392282958199357,0.8392282958199357,0.8392282958199357,0.8392282958199357,0.8392282958199357,0.8392282958199357,0.8392282958199357,0.8392282958199357,0.8392282958199357,0.8392282958199357,0.8392282958199357,0.8392282958199357,0.8392282958199357,0.8392282958199357,0.8392282958199357,0.8392282958199357,0.8392282958199357,0.8392282958199357,0.916721352852095,0.916721352852095,0.916721352852095,0.916721352852095,0.916721352852095,0.916721352852095,0.916721352852095,0.916721352852095,0.916721352852095,0.916721352852095,0.916721352852095,0.916721352852095,0.916721352852095,0.916721352852095,0.916721352852095,0.916721352852095,0.916721352852095,0.916721352852095,0.916721352852095,0.916721352852095,0.916721352852095,0.916721352852095,0.916721352852095,0.916721352852095],\"num_epochs\":{\"__ndarray__\":\"AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/\",\"dtype\":\"float64\",\"shape\":[192]},\"num_steps\":{\"__ndarray__\":\"AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/\",\"dtype\":\"float64\",\"shape\":[192]},\"precision\":{\"__ndarray__\":\"UK7HUKyT6j97cjRNqRLrP9qWc7ao6uo/OgAzgcEs6z+cbcvEH0DrP9u1a9euXes/qUHpNwFd6z/vNfDS6V7rP5EQVoYom+s/krPPhoqn6z8zyoPAEtzrPzS/DDS/DOw/JXaRAFM17D96Bw5VWoLsP3QdtYLR3+w/+hRkceMH7T8VBpEblVftP18gu4KAiu0/atK9r89o7T/+mjN9F1vtP4S1d3b4gu0/27Zt27Zt7T/Ui6R28HvtP1qcpWasa+0/TDU9/hqJ7T8rsRBHGqXtP3nSJfyQxu0/H1Y8tAYU7j8f/3lqJyDuP5ZQCiCFJe4/3UfI2ic57j+AA0Gb0D3uP1ZBWFCDS+4/j8BY9wBr7j/x2o9Yd5LuP1oL8t7Jqe4/2Pz03LbD7j+w/bW/9tfuP5NvnbAj1u4/dquBsAbj7j/OX/JY/tjuP6Sydlp92u4/1QE0rr3p7j/HlHpHteLuP59aFw9M5u4/T67YQDbc7j9dwg5OT9vuPxtGp4k43u4/iVFeFoI87j/OByPlIT3uPzR4rVSKP+4/QgPJFsha7j8XzKkww33uP3ztB8RJe+4/0LXLYzWP7j+ALoxfoZbuP+nnu6y8pu4/hvulfx2p7j8dHJRBD8TuP/TTtmvSze4/GDDEgoLe7j8wIv+Lr93uP8QpYWEC6+4/NA8vKN787j/YMAf0hPzuPxg7GVfF/+4/iTc5bEoC7z8GU3171wTvP8o/r6UgAO8/sWasYq8I7z8t8wyp/gjvPwZ62T0NBO8/MkW2mdXq6j84x1SJwyrrPw/xwLkdLus/ypdPKAaL6z+JWmgdBprrP9Qt1fEsrus/HBllJuiK6z8Bm0cYEozrPy30nRijg+s/EfkgD7ef6z+GVM62h8LrPzESLn/fses/ZLywHVTq6z+XaIAhu/DrP6szCDcMHuw/HwpxwMoC7D/XTExLHtzrP1eSbc2i6Os/JeJBtWfw6z8Aonv5a/brPz5mwvhvEuw/orJ5T9fK6z8ftNejMOzrP9Ne6VnZDew/rH14KDic7T+0eV5xGhDuP4EXJ0lRNO4/d70IaM5v7j/t4Xcd/o3uP/OhOmG5n+4/mGqRMpWx7j+9mDUOFbzuP1AGJnMtwO4/fpXQdT/Q7j+zTQRRrunuP7m9C5iR++4/vkLdPNQE7z9Vwv+PSgfvP+u1aGS+A+8/1/JV//4F7z8d2Kn/Yf7uP21UVfqaAe8/Lly/JfMD7z8wrpqaTALvPxK4WTGMAe8/+RosodwB7z/aT0dP+P7uP4doPVn2/O4/mYVKmYVK6T/pw37KRqbqPyZgy5JL9+k/NFo9OF7W6T9A5ijdvrLqP2sZOmC3x+o/TLwfOc3X6j+NBXgDK+LqPwhxMPBmvuo/Po2w3NMI6z/bWe2sdlbrPwGBQWITnes/xvYmBub76z+cuZu5m7nrP3ZOijA3Lew/AfOB7MJi7D8bymsor6HsP4kCk07Ng+w/yYS6dP5o7D97XW1PaobsPwdodzSyYew/yEPwVT6/7D/LLasTwM/sP09+JQbsAO0/gzXqTzdH6T+uTdUZ0KjpPyjPvW+Qo+k/CpRCMueN6T/7inOp4JTpPy+O31lsqek/8Y1HThEp6j9IEGgIpRPqP6kjXXGLOuo/MqMfmF036j9esqUBXb7pPyzEc/XZN+o/40yIlB5Z6j/7K/iZT4bqPySQETOqiuo/zhdFJSty6j9L/v5u2MfqPwLrRPL37uo/TIZgHW3e6j9dGnZHxQvrP62DwxQfz+o/x9hygors6j+YBeDucRTrP1wEk6+uleo/7ACAjU776z+DvR8Ve6/sP7O25qYdYuw/k3zUm9n67D+d51HCe/fsPxuyKGEO/+w/JdEopy8b7T+5XdWo+VDtP+TEH43ZPu0/courzy9x7T8Y2QNUKpztP2mphgO7xO0/w6UIxujd7T/zDkqq9ertPw8OrMSE7u0/w81nq3Dz7T8f4aIc/OntP3R0S7dN2O0/fgNgUKLv7T8jG++G+/7tP7KyDMV/7u0/s2qFRG7y7T8IkAtWyuztP9IF03Jx8O0/\",\"dtype\":\"float64\",\"shape\":[192]},\"precision_errn95\":{\"__ndarray__\":\"24dVEQ0NhD/LolCxjoiDP6iashMToIM/i37jxgcZgz9VQ4ZUcfKCPxrRs+9q14I/JV2te2bCgj+pOiws25WCP49ubkeRRYI/WoUf4i0Tgj+txmND8p+BP/GDuP2jXIE/9/NO5IrzgD+6XtBp32aAP+OVJmdPQX8/dOzhoouPfj/CscMYsSx9P8RP23haKXw/MdVYsY21fD8zarVKKQB9PyKWJqgWS3w/Q1Nx7fGYfD8F0rM1Ol98P1xVcqClrnw/7hItxc0+bD+uJ5odHoFrP066Pe7vsmo/laTVtpW2aD9jWTQoe2NoP07WTldmTGg/yzg9+urKZz+lNcCPgqdnP7pa5V+TTWc/wphGb4JqZj89oH4aekJlP3UeVHgrh2Q/t4PuvS3DYz/01URPwB1jP7CSPCaKLWM/B4An0XzBYj9bI+nFyw9jP1JBJF9ABWM/E4jRJx2KYj+NhlO5JMFiP3bK6y2DpGI/jBpc+jj0Yj+KE0Oxaf1iP6E5VXrB5mI/+84K37P+aT/N06Vg5P5pP+9a711z4mk/IVyP0WMaaT/xziRBHQ1oP2UI1NT6H2g/sbwX4F+IZz+oSlT8001nPzJhLcUM02Y/b/yDKIS5Zj/fEzYkJtNlPxFuRFGKg2U/sSs21a3xZD+23X2JifFkP1fnvmLedmQ/XmKq+4PRYz+FCWHtOdhjP69bC/hvtWM/IsyDZZ2cYz/B85+KGIdjPyav5JOOtmM/AhfROT9kYz/yXAtFOWJjPw48OB2SlmM/1b3EmfyMWD/8uM2SWvJXP6mKPC2azFc/LWmxIOmbVj8Mv9vJfmJWP9wSejhnQlY/iyst7eaAVj/0d9N6TGdWP0DRI564WVY/IO468PMBVj/K92xQ5qRVPzCCdQqFl1U/VfC++JVPVT/4r4TiiEtVP04XvUNV/1Q/tTLW1TUWVT+fGLCPXG5VP6f/LPuMOFU/j3k5DGA0VT8MI2pCryVVP0yi4ZnpElU/ovcxpw6IVT9IAdY/p0tVP7ZqyVjSElU/Zpyny7ilTz+znikNWKxMPwYBXDcpo0s/Zud/H//OST//1iDYMNtIP9vFjQQUSEg/wiLzMwqqRz9KFWJd5ktHP0XgevV9Jkc/ASksTv2VRj+xKFR4LadFP+VWLykf90Q/w+ju0f+URD9KlZ1G6n5EPyy1HkXwpkQ/WjQu91aMRD+AhqLvKdlEPwIy/Ba6uUQ/drSf7U+gRD8PQwO037JEP6QI6HQGukQ/c9FBP7e3RD84MWvDW9NEPwtOAnaJ5kQ/SXk7Nau6nz/vAGn7ngeeP0zol4lP3Z4/7svrLFbknT8ekAmuPrOcP0QSV8aw7Zs/eik3XzRjmz8/o8UY1hObP4gL+YnZ9Jo/oCJeVuF2mj8NifSJFMWZP6H8hkPQ8Jg/KHqmsYhLmD/0XoXBXpeYP4r8eAPFdZc/fT+pbX2hlj9IhGz74M2VPzzjdVkD/5U/SuhWBcT/lT9DdeVkL5KVP/wIZOtI0JU/LmTjUzjalD/dUb87GdSUPzz4FTkzQpQ/D8TlLKZrhT/DJnp5hy2FP0PyYDHoHYU/tYsvHVT9hD+kBgXx/e2EP0NXhCrt0oQ/hiawoY+EhD+k1dsAy36EP2TEsElrUIQ/tr+r75k8hD+uNSJSznKEP1+KZy7IEYQ/0kUkCij/gz/Tt4W6VdCDP+chsq2pv4M/2uurLG6tgz9SjIFPQWSDP7iWBTFyNoM/jkBez0c/gz9chYIn3w2DP6pOqkUQLYM/1TJl0IkUgz9AETOdKOqCPysYq1c+WYM/MkJIdwrzYz+hThc6phliP87YXJvB/WI//MC8jHFRYT/7GS/tSFBhP1LHSHtwPWE/wiITdy7cYD9TfdokdjJgP3F3COhvbmA/6VrY7fGwXz9ztbEoeH5eP5oF50XJpl0/JQvwEv3hXD/JjcEaUHtcPz7le3S8alw/+enMaew3XD+tjJNn03ZcP5514C415lw/DWU6CQhZXD+5eMYmAfNbP0peVtACTlw/gYbmrf1IXD+MbwgdxVlcPzKp387WVFw/\",\"dtype\":\"float64\",\"shape\":[192]},\"pred_pos_count\":{\"__ndarray__\":\"AAAAAAAJtkAAAAAAAH21QAAAAAAA1rVAAAAAAAAZtkAAAAAAACm2QAAAAAAA9bVAAAAAAAAptkAAAAAAAIy2QAAAAAAAVbZAAAAAAACctkAAAAAAANO2QAAAAAAAmLZAAAAAAADhtkAAAAAAAL22QAAAAAAAt7ZAAAAAAACxtkAAAAAAAIe2QAAAAAAAhbZAAAAAAAC6tkAAAAAAALG2QAAAAAAAjrZAAAAAAADAtkAAAAAAAKi2QAAAAAAArrZAAAAAAIBu1kAAAAAAwLDWQAAAAAAA2NZAAAAAAABF10AAAAAAQFfXQAAAAACARNdAAAAAAIBS10AAAAAAQF7XQAAAAAAAY9dAAAAAAMCL10AAAAAAAL/XQAAAAABA6tdAAAAAAIDt10AAAAAAQP/XQAAAAAAA/NdAAAAAAMAH2EAAAAAAwA3YQAAAAABACthAAAAAAAAJ2EAAAAAAQA/YQAAAAADADdhAAAAAAIAS2EAAAAAAgA3YQAAAAADAC9hAAAAAAABn00AAAAAAQGDTQAAAAADAcdNAAAAAAIB800AAAAAAgI3TQAAAAABAjdNAAAAAAICL00AAAAAAQIzTQAAAAACAgtNAAAAAAECN00AAAAAAQJnTQAAAAAAAktNAAAAAAMCQ00AAAAAAwJ7TQAAAAADAo9NAAAAAAICi00AAAAAAwJvTQAAAAACAo9NAAAAAAACl00AAAAAAAJ/TQAAAAACAmtNAAAAAAECa00AAAAAAQJjTQAAAAABAj9NAAAAAAEjnC0EAAAAAiCUMQQAAAADYbgxBAAAAAKiFDUEAAAAAsMgNQQAAAABoqg1BAAAAAFjNDUEAAAAACAsOQQAAAABwXw5BAAAAALCuDkEAAAAAGOMOQQAAAABwcA9BAAAAAEjdDkEAAAAAoL8OQQAAAABocA5BAAAAAFDkDkEAAAAAUN8OQQAAAABwKw9BAAAAABAFD0EAAAAAsAgPQQAAAACwhQ5BAAAAACgCD0EAAAAAqNwOQQAAAACYpA5BAAAAAOBeEUEAAAAAOGoRQQAAAAAsdRFBAAAAABCQEUEAAAAA8JIRQQAAAACokhFBAAAAAJCaEUEAAAAA/J0RQQAAAAC0nxFBAAAAAAyfEUEAAAAAqJ8RQQAAAABgoRFBAAAAAMypEUEAAAAApKQRQQAAAAD0nRFBAAAAAEikEUEAAAAAeKQRQQAAAADQohFBAAAAALSlEUEAAAAAjKIRQQAAAABMoxFBAAAAANShEUEAAAAAVKQRQQAAAADkpRFBAAAAAAC4hEAAAAAAAHCDQAAAAAAAOIRAAAAAAADohUAAAAAAACCFQAAAAAAACIZAAAAAAACwhkAAAAAAABCHQAAAAAAAyIdAAAAAAACQh0AAAAAAAJiHQAAAAAAA8IdAAAAAAABoh0AAAAAAABiIQAAAAAAAEIhAAAAAAACgiEAAAAAAAPCIQAAAAAAAQIlAAAAAAADoiUAAAAAAADCKQAAAAAAAiIpAAAAAAABwikAAAAAAAAiKQAAAAAAACIpAAAAAAADDtkAAAAAAAEy2QAAAAAAAe7ZAAAAAAAD7tkAAAAAAAAq3QAAAAAAADrdAAAAAAABOtkAAAAAAAJq2QAAAAAAAjLZAAAAAAADCtkAAAAAAAK23QAAAAAAAIrdAAAAAAADktkAAAAAAAL22QAAAAAAA1bZAAAAAAABRt0AAAAAAANm2QAAAAAAAubZAAAAAAADgtkAAAAAAAK+2QAAAAAAAQ7dAAAAAAAATt0AAAAAAAOS2QAAAAAAAo7dAAAAAAKBd8UAAAAAAkNbxQAAAAACgfvFAAAAAAODv8UAAAAAAMATyQAAAAAAAA/JAAAAAAGA28kAAAAAA4G7yQAAAAADgVvJAAAAAAJBv8kAAAAAAALbyQAAAAACAk/JAAAAAAPDG8kAAAAAAYOHyQAAAAABA2fJAAAAAAADz8kAAAAAAkO/yQAAAAAAw7/JAAAAAAFDn8kAAAAAAYOvyQAAAAADA//JAAAAAANDk8kAAAAAAkP7yQAAAAAAA5vJA\",\"dtype\":\"float64\",\"shape\":[192]},\"prev_layer_score\":[0.8046756386756897,0.8185550570487976,0.8232068419456482,0.8252018094062805,0.8381749987602234,0.8417109251022339,0.8413406610488892,0.8451955914497375,0.852824330329895,0.8560270667076111,0.8628600835800171,0.8733797073364258,0.8748921751976013,0.8853639960289001,0.8920615911483765,0.9030203819274902,0.9074472784996033,0.9138512015342712,0.9198859333992004,0.9199931025505066,0.9176065325737,0.9196891188621521,0.9210662245750427,0.9209029674530029,0.8563817739486694,0.8819051384925842,0.8904747366905212,0.8975300192832947,0.915321409702301,0.9182020425796509,0.9173614382743835,0.9208033680915833,0.922286331653595,0.9242936968803406,0.9312691688537598,0.9400315880775452,0.9462287425994873,0.9496089816093445,0.9534448385238647,0.9529696106910706,0.9554478526115417,0.9547053575515747,0.9546121954917908,0.9563573598861694,0.9559973478317261,0.9563137292861938,0.9554662108421326,0.9549658298492432,0.9059931039810181,0.9334692358970642,0.9329020977020264,0.9348565936088562,0.939168393611908,0.9450168609619141,0.9446935057640076,0.946938157081604,0.9479081630706787,0.9489239454269409,0.9502415060997009,0.9546545147895813,0.9551418423652649,0.9570427536964417,0.9582890272140503,0.9603855013847351,0.9624320268630981,0.961739182472229,0.9628806114196777,0.963330864906311,0.9630618691444397,0.9620559811592102,0.9630692601203918,0.962913453578949,0.7355877757072449,0.7950003743171692,0.8060488700866699,0.8107266426086426,0.8377071022987366,0.843295156955719,0.8439799547195435,0.8417536020278931,0.845357358455658,0.8490377068519592,0.8567987680435181,0.8639011383056641,0.869543194770813,0.8684184551239014,0.8675548434257507,0.8686078786849976,0.871780514717102,0.8668035268783569,0.8725050091743469,0.8713492751121521,0.8722816705703735,0.8684029579162598,0.866614043712616,0.868610143661499,0.8851251602172852,0.9166030287742615,0.9318123459815979,0.9373550415039062,0.9474194049835205,0.9513950347900391,0.9535217881202698,0.9565359950065613,0.9581786394119263,0.958860456943512,0.9607478380203247,0.963910698890686,0.9662739038467407,0.9683055877685547,0.9680526852607727,0.9669022560119629,0.967856228351593,0.9669485688209534,0.9671635627746582,0.9677594304084778,0.9672196507453918,0.9672085046768188,0.9670891761779785,0.9670050144195557,0.6072974801063538,0.6453201770782471,0.6544535756111145,0.6529850959777832,0.6811071038246155,0.6890653371810913,0.7082833051681519,0.7219917178153992,0.7298410534858704,0.7386759519577026,0.7428571581840515,0.751748263835907,0.7654892802238464,0.7660818696022034,0.7713626027107239,0.7833622097969055,0.7993139028549194,0.8118249177932739,0.8140192031860352,0.8223463892936707,0.8304613828659058,0.8320441842079163,0.8411732316017151,0.8361204266548157,0.7766251564025879,0.7811625003814697,0.7846733927726746,0.7873303294181824,0.79351407289505,0.7953778505325317,0.7981449961662292,0.8001371026039124,0.8029631972312927,0.8066496253013611,0.8100814819335938,0.811381995677948,0.8168350458145142,0.8165510296821594,0.8192545771598816,0.8214860558509827,0.8271988034248352,0.8291691541671753,0.8315923810005188,0.832402229309082,0.8343391418457031,0.8375723958015442,0.8377581238746643,0.8392282724380493,0.8131866455078125,0.8177706599235535,0.850328803062439,0.83277428150177,0.8615527749061584,0.8631550669670105,0.8639200925827026,0.8722233772277832,0.8840294480323792,0.8795674443244934,0.887890636920929,0.8998007774353027,0.9012567400932312,0.9092509746551514,0.913365364074707,0.9130033254623413,0.9160792231559753,0.9146183729171753,0.9124705791473389,0.9144967198371887,0.9167213439941406,0.9167159795761108,0.9145888090133667,0.9163974523544312],\"prev_score_max\":{\"__ndarray__\":\"AAAAIOe/6T8AAABgmjHqPwAAAOC1V+o/AAAAoA1o6j8AAABgVNLqPwAAAMBL7+o/AAAAwEvv6j8AAACg1wvrPwAAAEBWSus/AAAA4JJk6z8AAADAjJzrPwAAAAC68us/AAAA4B3/6z8AAADg5lTsPwAAAMDEi+w/AAAAAIvl7D8AAADgzgntPwAAAOBEPu0/AAAAoLRv7T8AAABglXDtPwAAAGCVcO0/AAAAYJVw7T8AAADgX3ntPwAAAOBfee0/AAAAwHpn6z8AAAAgkTjsPwAAAODEfuw/AAAA4JC47D8AAAAgUErtPwAAAEDpYe0/AAAAQOlh7T8AAACgOHftPwAAAKBeg+0/AAAAYNCT7T8AAAAA9cztPwAAACC9FO4/AAAAgIFH7j8AAABgMmPuPwAAAMCegu4/AAAAwJ6C7j8AAABgB5PuPwAAAGAHk+4/AAAAYAeT7j8AAADAepruPwAAAMB6mu4/AAAAwHqa7j8AAADAepruPwAAAMB6mu4/AAAAQOX97D8AAADg+t7tPwAAAOD63u0/AAAAYFjq7T8AAADgqg3uPwAAAACUPe4/AAAAAJQ97j8AAABAUU3uPwAAAIBDVe4/AAAAwJVd7j8AAADgYGjuPwAAAKCHjO4/AAAAoIWQ7j8AAAAgGKDuPwAAAMBNqu4/AAAAYHq77j8AAABAPszuPwAAAEA+zO4/AAAAAOvP7j8AAABAm9PuPwAAAECb0+4/AAAAQJvT7j8AAABAm9PuPwAAAECb0+4/AAAAYO+J5z8AAACgpHDpPwAAAAAny+k/AAAAAHnx6T8AAAAgf87qPwAAACBG/Oo/AAAAQOIB6z8AAABA4gHrPwAAAOAqDes/AAAAIFEr6z8AAABA5WrrPwAAAAAUpes/AAAAQEzT6z8AAABATNPrPwAAAEBM0+s/AAAAQEzT6z8AAABAoOXrPwAAAECg5es/AAAAoI/r6z8AAACgj+vrPwAAAKCP6+s/AAAAoI/r6z8AAACgj+vrPwAAAKCP6+s/AAAAAPJS7D8AAADgz1TtPwAAACBo0e0/AAAAAND+7T8AAACAQlHuPwAAAADUce4/AAAAIECD7j8AAABg8ZvuPwAAAEBmqe4/AAAAIPyu7j8AAABAcr7uPwAAAEBb2O4/AAAAQLfr7j8AAAAAXPzuPwAAAABc/O4/AAAAAFz87j8AAAAAXPzuPwAAAABc/O4/AAAAAFz87j8AAAAAXPzuPwAAAABc/O4/AAAAAFz87j8AAAAAXPzuPwAAAABc/O4/AAAAIPtu4z8AAACAdqbkPwAAAKBI8eQ/AAAAoEjx5D8AAAAgocvlPwAAAMDSDOY/AAAAwEGq5j8AAABgjhrnPwAAAKDbWuc/AAAAwDuj5z8AAABgfMXnPwAAAGBSDug/AAAAYON+6D8AAAAgvoPoPwAAAKAAr+g/AAAAoE0R6T8AAADA+pPpPwAAAEB4+uk/AAAAAHIM6j8AAABgqVDqPwAAAMAjk+o/AAAAIBug6j8AAAAg5OrqPwAAACDk6uo/AAAAAB3a6D8AAACASP/oPwAAAGALHOk/AAAAYM8x6T8AAACgd2TpPwAAAEC8c+k/AAAAYGeK6T8AAAAguZrpPwAAAODfsek/AAAA4BLQ6T8AAAAAMOzpPwAAAGDX9uk/AAAAQIMj6j8AAABAgyPqPwAAAGBVN+o/AAAAIJ1J6j8AAACgaXjqPwAAAMCNiOo/AAAAoGec6j8AAAAACqPqPwAAAADosuo/AAAAoGTN6j8AAAAg6s7qPwAAAED12uo/AAAAAKAF6j8AAABgLSvqPwAAAMDkNes/AAAAwOQ16z8AAAAg15HrPwAAAGD3nus/AAAAwDul6z8AAAAAQenrPwAAACD4Sew/AAAAIPhJ7D8AAACgmWnsPwAAAAAry+w/AAAAYBjX7D8AAACAlRjtPwAAAABKOu0/AAAAAEo67T8AAABghVDtPwAAAGCFUO0/AAAAYIVQ7T8AAABghVDtPwAAAADIVe0/AAAAAMhV7T8AAAAAyFXtPwAAAADIVe0/\",\"dtype\":\"float64\",\"shape\":[192]},\"real_delta_score\":[0.013879441257917402,0.004651805956420341,0.0019949832561770853,0.012973188412789494,0.003535951670998738,-0.0003702407581366307,0.003854913478508748,0.007628730540243489,0.0032027459523230606,0.006833033344139872,0.010519605663694698,0.0015124410673706956,0.010471796336309458,0.006697584774402521,0.010958802965727377,0.004426884538286768,0.006403926892257106,0.006034720166532503,0.00010718428834255445,-0.0023865592874846575,0.0020825865972845525,0.0013770892203930352,-0.00016324335843065363,-0.0015092368295099856,0.02552338412121402,0.008569574507726108,0.007055262072416357,0.017791407828561145,0.0028806265752692184,-0.0008405908876449875,0.003441958198510009,0.0014829754309192422,0.00200736152590697,0.006975476846320716,0.008762393481853148,0.0061971665344429105,0.003380222973357938,0.003835858678077675,-0.0004752391681167589,0.0024782240535842215,-0.0007424787750688333,-9.31750350343652e-05,0.001745151356686736,-0.0003600133125067906,0.0003163571601318971,-0.0008474913440715826,-0.0005003885662981933,0.0002148349005205441,0.02747614170542223,-0.0005671336455403964,0.0019544774873441195,0.004311809685775048,0.005848448076223534,-0.00032336250990172566,0.0022446630826036262,0.0009699948096050237,0.0010157682989533345,0.0013175406411705115,0.004413022262864885,0.00048733796082711667,0.0019009168018350175,0.0012462807948429022,0.0020964911351403215,0.0020465302514487416,-0.0006928534156666055,0.0011414027393170656,0.00045025094750783534,-0.0002690046481890196,-0.0010058683529091672,0.0010132547474859255,-0.00015577883683715044,-0.0014692815263527281,0.05941261708359613,0.011048502584685815,0.004677767840125413,0.02698045911417002,0.005588037376253352,0.0006848171085261923,-0.0022263614877978677,0.0036037674074740345,0.003680337968767655,0.0077610405887247325,0.007102365457741455,0.005642029694835293,-0.0011247324085661425,-0.0008636008267759454,0.0010530576228330313,0.0031726639764402265,-0.004976981917454881,0.005701492956110887,-0.0011557425120003462,0.0009323786396909783,-0.0038786941524872054,-0.001788927583590283,0.0019961060253524954,0.0009686456541324606,0.03147784041096369,0.015209346190759088,0.005542698806958457,0.01006439317583152,0.003975623955219332,0.0021267767882398037,0.0030142324732994608,0.0016426685079516945,0.0006818248203487309,0.001887400396825334,0.003162874383283776,0.002363190365777923,0.002031677022008127,-0.00025292474215765637,-0.0011504127298819222,0.0009539925309216546,-0.0009076714488512883,0.00021502250903249198,0.0005958623098627491,-0.0005398029488270506,-1.1122820999132088e-05,-0.00011931107103668737,-8.414386688015973e-05,-7.716398841250971e-05,0.038022716937981205,0.009133392094210269,-0.0014685009842487773,0.02812200390187991,0.007958259645146293,0.019217976144238813,0.013708396076661522,0.007849365174594891,0.008834904702282875,0.004181190899440135,0.00889109356420037,0.013741023946374331,0.0005925911211828172,0.005280717002877577,0.011999615660160057,0.01595168385661072,0.012510997656734912,0.0021943021049737332,0.008327165529048552,0.008114978132677364,0.001582816029121914,0.009129031066018478,-0.005052830263922337,0.005574110691895617,0.0045373382940604445,0.0035109095276679714,0.002656923969406866,0.006183731894206845,0.0018637948512387759,0.0027671747625778176,0.0019921310192352326,0.002826112654943258,0.003686419136993635,0.0034318410937509425,0.0013004966003941076,0.005453021157068916,-0.00028402195260857077,0.0027035759719707952,0.002231485705491698,0.0057127368043372595,0.0019703335278200562,0.0024232025207228114,0.0008098536363528863,0.0019369122123800153,0.0032332580535665567,0.00018571629285113467,0.0014701719452714368,-0.0020228431766619037,0.004584003207641407,0.032558127296263395,-0.017554504694995754,0.028778523180469584,0.0016022635029485643,0.0007650167744763792,0.008303272287720986,0.011806069119540519,-0.004461980190427761,0.008323213123796913,0.011910157364277807,0.0014559550602089022,0.007994227309569446,0.004114361373145803,-0.0003620136732909174,0.0030759169179565005,-0.0014608450094321102,-0.002147781713638053,0.0020261541165566,0.0022246330149062743,-5.350895643019271e-06,-0.0021271871530643693,0.0018086290640578762,-0.0019309952916636286],\"real_headroom_frac\":[0.11924885819738537,0.03996721039058294,0.017140421649633177,0.11146254929550593,0.03038005576537206,-0.0031810205357324533,0.03312049975352221,0.06554423838211923,0.02751723148026277,0.05870779732206643,0.09038194987617033,0.012994533931393479,0.0899711835062617,0.057544055426013214,0.0941554286364117,0.038034739061359575,0.05502101674630216,0.05184888037111926,0.0009209019126946332,-0.02050474977806233,0.017893088720822545,0.011831623054286953,-0.001402548109784854,-0.012967003881791192,0.2552961451987966,0.08571666388070989,0.07056984300753828,0.17795750809220312,0.028813297520848605,-0.008407960805112571,0.03442798399467113,0.014833374333912536,0.02007851533913474,0.06977179598644982,0.08764532430371803,0.06198679296932539,0.033810481044065,0.038367950323117364,-0.004753551766156646,0.0247882900172759,-0.007426600182279491,-0.00093197779573694,0.017455773577464858,-0.0036010119373959273,0.003164343846574142,-0.008476982213772787,-0.005005107139037365,0.002148873429032305,0.4791982211336487,-0.009891106145895561,0.0340871052865562,0.07520020654437398,0.10199998036717652,-0.005639610582429029,0.03914809319882639,0.016917214660451055,0.0177155281538795,0.02297859496756056,0.07696540660112836,0.008499427846274655,0.033152979036450446,0.02173578613491763,0.036563897265948664,0.035692553434345645,-0.012083724412743479,0.019906658225229384,0.007852611018777643,-0.004691581164156769,-0.01754286793889932,0.017671690507210475,-0.0027168640452855117,-0.02562503503298699,0.43393080373117005,0.08069473862517886,0.034164924189038576,0.19705666713813655,0.04081324252297465,0.005001685717589329,-0.01626063414168284,0.026320767613806483,0.026880014569003505,0.05668416484190521,0.05187341178951657,0.041207585195417534,-0.008214686744818612,-0.006307464967222522,0.007691196972660172,0.02317212566698648,-0.03635028836649214,0.04164188588817257,-0.008441174648693595,0.0068097961739946354,-0.028328744863199494,-0.013065756438097056,0.014578921690911177,0.007074678879016351,0.3784284742308631,0.1828476667355257,0.0666346555308144,0.12099473483139221,0.04779518822915531,0.025568237353502887,0.03623728251225715,0.01974825874378391,0.008196938642824872,0.022690440103526475,0.03802426441659814,0.028410415478405303,0.024424942293711224,-0.0030406763304073217,-0.013830330429953717,0.01146895508684831,-0.010912080276386219,0.0025850134239233467,0.007163492216400578,-0.006489543235589698,-0.0001337192172299884,-0.001434364809713496,-0.0010115825845617107,-0.0009276700694607807,0.16221498189598205,0.03896546992230503,-0.006265014174623446,0.11997591758797638,0.03395204362609319,0.08198897667938805,0.058483648736245904,0.033487470970807134,0.037692043645149255,0.01783806788879979,0.03793176021336738,0.05862284787089483,0.002528150688210505,0.0225289374879972,0.0511935388585347,0.06805410860647258,0.05337522991053467,0.00936147400547985,0.03552589384242925,0.03462064620541661,0.0067527124357650865,0.03894686462089184,-0.021556712297086854,0.023780632679324145,0.07247782669231503,0.056082018969539724,0.04244075766653939,0.09877673197230072,0.02977159547370385,0.04420186458920255,0.03182159173573683,0.04514331750093816,0.058885546990404526,0.05481900795319719,0.020773669739524464,0.08710461877813493,-0.0045368655638756035,0.043185960148158196,0.0356449582877082,0.09125322407314639,0.0314734063674154,0.03870737444621078,0.012936313692669019,0.030939546172008905,0.05164691316155298,0.002966565950091014,0.023484003296992732,-0.03231217680545297,0.04427504907852022,0.3144658977427871,-0.1695519225694335,0.2779602169777315,0.015475620765603718,0.007388990299869476,0.08019797792426021,0.11403008811614881,-0.04309647767899822,0.08039057846486555,0.11503543473906527,0.01406248617789181,0.07721303638837286,0.03973896689669341,-0.0034965449250411143,0.0297090482565448,-0.014109716236869104,-0.020744562443314917,0.01956981024831055,0.021486838349607178,-5.168215563501218e-05,-0.020545647839889162,0.017468822980427713,-0.018650709311520762],\"recall\":{\"__ndarray__\":\"II//AlLS6T8sbeatlKbpP0rT/HtO6uk/SmzsUTl66j+7BdnVUaDqP6zSze50fuo/SLC364m86j8+J/V84TXrP5t8fXfTLus/h9EIxJeR6z9cJvsghgnsPzLi/aeJ8es/DEhJp8F07D/6WAlaNZXsP8F68M9G6+w/r4uwgroL7T/78fgvICXtP1B68yEZVe0/gM9JPV947T80aQGQ+V7tP7Lg1L5UWe0/pQLuExKF7T8eaWigI3TtP1qcpWasa+0/6CO9zLUE6z9SZFjTaW7rP6ohx84Jves/STENC+aK7D99izX606zsP/DRWHTimuw/C0USgMW+7D8LizeUsdHsPwvRXKid5Ow/SKdcwDI17T/ntdWN/JrtP1las2yn5+0/zM8zGQQF7j8TZ2P/GS/uP2IcsKk6Ke4/73ifOaJE7j+OhkuYWULuPzbhce1pP+4/AbamMMpM7j90Qu++xE3uP96BvVZmT+4/E1CbHXxL7j90n9y0TkTuP2tSYr71RO4/5CZ2Z6+D7T/SGy6XBnrtPwc9BggBl+0/tMOcqBHC7T/hCF++cP7tP/xan4Gf++0/W24d7oYM7j8KeFyk+hTuP0vOt7XIFe4/TTmaTbMo7j+fF5UZx1XuPxxr3vYqVO4/tntKL6hi7j9cPpHylXfuPwIB2LWDjO4//hJNCDac7j+KBvwdWJHuP2Ztw2ejoO4/73Lnz3el7j/CFV88oJ7uPw2zskD0ku4/nBFE7gCb7j+3Y4SxL5juP7X4oRlFhe4/oDmcEM4d6D/2mL4AYo3oP/6pLs5k0Og/Klecwckb6j8/pXDYaWXqPxgeIobFXeo/kRu7DhNb6j8hq9JBwJLqP3vyPhov1eo/FRe/2ds26z/MWaeA3ofrP3Ob5PMJ9es/vHDrESGq6z96ix9a3pXrPx5gxQEXe+s/XI0lW7LI6z8bnH4X3Z3rPwgDDxt97us/7yDSo9bT6z/huw70Fd3rPyvVv6Xsgus/eXuvuNSr6z9eTRDdaavrP72YSnhEmus/Orusq7wO7T8gJ4xSuZPtP4uNf/wKyu0/iF6GyvMy7j/V8c6Y3VXuP1ANmbn7Zu4/ZUfFFmyG7j+DqXY0zpbuPwMWeAPene4/YKiTpLms7j9zXKmdG8fuP0RFIQnt2+4/poeNWujz7j/jMeF5U+3uP1QUB5wS3u4/79aMwGfr7j/WJCxTJeTuP34kVN505O4/Kb+vc9vr7j+bmOW3ruTuP+I60Vc/5e4/xLEi2Pzi7j8BU4YZfOTuP18Mnxw45e4/rXj7UNBy4T/tBmbBqj/hP/dglJNWe+E/6ZQRPtfY4j9UxN+4ysfiP+dbZ3xtpeM/cZnAbWRH5D+llFJKKaXkP08Z4XONLeU/mQF6thM25T/uQ0HLRXrlP5fIz/SpAuY/2FY6ZYTP5T+hIv7GVT7mP4s192CUk+Y/qkOC15dG5z8J4He+dcbnP8hRDU6b+ec/cdabd/+B6D+m0S1UxN/oP2VDw+PpEuk/cJ3xtZVO6T+GivgbV/noP/sT9Wj2I+k/uuMiju646D+7VKLVLpXoP7oPI3juw+g/Nu7kiI076T+1SyVa7VLpP7WupSita+k/N0lk200S6T+1SyVa7VLpP7WjJS7taOk/s4qmuqyi6T8uwWifSzDqPzA9aOFLD+o/sainKyzq6T+xqKcrLOrpPzAnaOzLCeo/rPqpAqt+6j+uKSlra0rqPy4vaWjLS+o/raKpLqto6j8tcWlHS1zqP6ouq2iqy+o/KsbqnIqx6j+riSq7aqLqP6j/KwDq/+o/u4ePNYiT6D+21BqcPOHpP7Hz5qEzHek/snbtw1VK6j+D2ecbCmXqP1SVLMQyauo//0sX53PP6j+vLZ7UxVTrP/ulehhgIOs/xhppq9Nz6z/Aae3rYgXsP/Urk/XU9+s/0mis/S9d7D+G8M+5lZHsP5bP0fGuiOw/vEJUsGG07D+ZWbR1HqbsP0yqQ5WelOw/IKj7ygmf7D/Go2s24LPsP3S+f5rywuw/AeT78eyd7D/p61Eqgr/sP9BdzQzTnew/\",\"dtype\":\"float64\",\"shape\":[192]},\"recall_errn95\":{\"__ndarray__\":\"DsFbVSTLhD/SYu4qXAKFPxkqCVUzrIQ/JAZeNjHogz/EhDpMK7GDP96oE2Yl4oM/xYRgg4OHgz/lFLDlLsuCP3f6RYKP1oI/YPtvuR0ygj86yPU5R1qBP/+8GcD4hoE/5kojNzWIgD96zxKBEkWAP0bG80ohFH8/UasuUMp/fj+htmezqgh+P+IFFYHoH30/mNzVVNRtfD91X/9Mqe58P2Tr4BncCn0/GrPt3i8sfD+0bQadhoN8P1xVcqClrnw/hE3roSdecj/iYQINWblxPx4dZ+SlNnE/BuVFu5d0bz/DTTW5DetuP1Vj4ANENG8/bF0tDL+gbj8DXAUlKlFuPxSRWoJKAG4/7N3r6maYbD/VXxGjKqlqPzSrjDBTEGk/6iTh2SxqaD+0hwjOgHFnP8wBQT7+lGc/u0JUlAjtZj9WhFMeQ/tmP8o3OyV+DWc/btoqAty5Zj+467g2rrNmP1AJHjRdqWY/DahRzRXCZj9x20ifEe9mP+kHLk//6mY/Oa5pzpcfbj8iYBKy71RuP7uvNRNUs20/8ybKPv+5bD+3VvdH+0drP0pIDsHTWWs/gNZM2tjtaj88XSoiBrdqPxMyIuXFsWo/0Moxa9k0aj8XXupIjf5oP/GAr8r1CWk/s6emM1yiaD+gc6lu5AhoPz0hXPuXamc/LofoBnfwZj+MF5I2VkVnPzMgy0h2zWY/UwWoCf2mZj86Y25OZ91mP2kEsunaOGc/lpmtx/f5Zj9llXzvERBnP9E5t571oWc/MFUELPNkWz/8QXp1p91aP4/HZKGgh1o/QPoQAeijWD9pIIV8zilYP/nLA5LANlg/lx0aU047WD/LNWepqdtXP7s8GijfZFc/CX3Y/lusVj+ZlfCAsQlWP/EK0fgvH1U/GgnLkxLCVT8THvs+o+xVP+LJ3K33I1Y/n4U8kayAVT+Ufg8M6ttVP9TiONrJLVU/Uk/Yp3loVT9DdzHDPVRVPycIE0TjE1Y/P44EJHi+VT9YVa2AWr9VPzPF/bty41U/YQRiOQg7UT+QWiGowoxPP8Dl7wSiPk4/019xJy18Sz/ypNdbx3tKP/qwSFiH+Uk/pc1g4sABST8sFwDN4ntIP2JCCvUbQUg/J9RZlDfDRz+Tdr/utttGPwwGHJIoHUY/8yGpRv43RT8q8DtO+3dFPxbKFdYUCUY/HaJN8H6KRT9SxN3R1M9FPyU8aU3izEU/4bW4YCWGRT8Mo/9FvcpFP2f3W6JfxUU/4vHREc3aRT/t2OSvncxFP+MrOFqkxUU/+OhxNI0eoD86NF2m7SKgP+IT5zLCHaA/ZkNVw+Hanz+V+OlAC+GfP8oerMUThZ8/gJ+7Kksxnz+7jKVKMvqeP95H+9AsoZ4/KpIfRUGbnj+fGYViW2qeP2TIBgUyAJ4/YPF0NlUpnj9FgEvZJc6dP/fVNQK7gp0/Ht1Ver7UnD9nsz9Y1UqcP4jLvPlREJw/9xEap3Jqmz8dRPcksu+aP+h0OoSWqZo/BuGS3d1Umj+hEZUz7cyaP/e4Gk61kZo/W0bajGbMhT8ey0tswPGFP0QrWVG8wIU/XCFMZXg8hT9xBoSNbiGFP68H7MxcBIU/tWxp1DdrhT9xBoSNbiGFPx075HGdB4U/Bf6s4hrChD/Br0UTZwyEPyFm/MM5OIQ/2k8G5W1ohD/aTwblbWiEP55YaoRwP4Q/4KdopX+ggz8viEDHCumDP1SDwRcq54M/1OGJDVi/gz8iI1tVgNCDPwt8nKb3MIM/USyoxHFXgz8EJ+Q7a22DP6W52/P54YI/+FH7JsTQZz/mJQ0PlzBmP05CGI2vL2c/MXgVtRqaZT+anKHCNnJlP+FTBIFtamU/OerTTSjMZD+DTutoxOpjPxqPpMDJRWQ/m8gQpz+zYz/KHPjeCp5iPziJRgIduWI/F2iyts3nYT80ItDX9HRhPxfBo/POiGE/bYOHIvQlYT/4eJv1m0ZhPyRDd+gnbmE//yFO1a1WYT890rlGHidhPwCCFWgzBGE/sicBITJZYT8f4SQYNQxhP4pnEqxsWWE/\",\"dtype\":\"float64\",\"shape\":[192]},\"run\":[\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-01-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-02-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-03-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-04-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-05-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-06-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-07-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-08-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-09-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-10-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-11-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-12-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-13-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-14-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-15-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-16-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-17-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-18-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-19-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-20-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-21-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-22-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-23-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-24-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-01-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-02-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-03-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-04-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-05-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-06-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-07-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-08-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-09-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-10-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-11-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-12-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-13-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-14-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-15-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-16-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-17-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-18-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-19-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-20-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-21-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-22-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-23-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-24-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-01-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-02-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-03-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-04-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-05-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-06-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-07-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-08-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-09-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-10-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-11-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-12-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-13-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-14-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-15-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-16-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-17-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-18-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-19-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-20-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-21-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-22-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-23-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-24-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-01-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-02-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-03-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-04-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-05-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-06-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-07-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-08-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-09-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-10-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-11-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-12-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-13-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-14-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-15-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-16-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-17-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-18-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-19-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-20-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-21-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-22-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-23-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-24-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-01-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-02-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-03-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-04-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-05-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-06-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-07-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-08-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-09-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-10-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-11-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-12-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-13-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-14-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-15-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-16-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-17-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-18-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-19-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-20-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-21-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-22-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-23-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-24-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-01-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-02-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-03-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-04-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-05-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-06-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-07-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-08-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-09-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-10-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-11-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-12-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-13-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-14-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-15-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-16-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-17-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-18-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-19-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-20-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-21-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-22-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-23-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-24-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-01-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-02-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-03-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-04-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-05-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-06-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-07-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-08-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-09-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-10-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-11-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-12-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-13-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-14-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-15-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-16-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-17-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-18-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-19-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-20-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-21-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-22-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-23-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-24-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-01-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-02-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-03-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-04-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-05-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-06-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-07-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-08-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-09-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-10-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-11-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-12-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-13-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-14-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-15-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-16-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-17-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-18-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-19-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-20-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-21-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-22-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-23-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-24-edges-srl-conll2012/run\"],\"score\":{\"__ndarray__\":\"p0NJbJox6j+9Z07rtVfqP1PseqgNaOo/HKZ+X1TS6j+MMJnNS+/qP0WrgUxD7Oo/GzbqltcL6z9dxYU7VkrrP4nsI+WSZOs/ndvXyIyc6z84W0n2ufLrP818ndEd/+s/Lm/Z0uZU7D8TL3K6xIvsP1nqigaL5ew/YRWK2c4J7T/aLhLiRD7tP0IvuJm0b+0/H2sgaJVw7T8VIb1lCF3tPxNyKuAXbu0/1Ekl11957T/yp2OHCXjtP1qcpWasa+0/+66CKpE47D/OCkjTxH7sPx+0+9SQuOw/QcBYKVBK7T9A2Z086WHtP54aNGcGW+0/lbI8rzh37T8PQF+mXoPtP1FcA17Qk+0/+7mdAvXM7T9HDi4SvRTuP0z8coaBR+4/2PVjVzJj7j+pYfLAnoLuP8sV6hm6fu4/zWRoVgeT7j/rLb5I8ozuP/axCNkujO4//xwAuXqa7j/UF1O/h5fuPwwD9TIfmu4/H5iM7i2T7j9eHu97FI/uP5XlmwrXkO4/DXFB5fre7T82R3GCVdrtP/ZxHFZY6u0/isgy5aoN7j8QCKf1kz3uPwoME9ztOu4/ZPhQRlFN7j9hgf95Q1XuP2r6c7iVXe4/GuE+1WBo7j/wdEmnh4zuP8FSk6WFkO4/reHvIhig7j/rLOjDTaruP7eTG2l6u+4/BgKQQj7M7j8rpCc7kcbuP1j77fHqz+4/dwajPpvT7j9+rDobZ9HuP90+iqopye4/UhgAk3bR7j8osd/uL9DuP4+pfJEmxO4/iwDrqaRw6T8CrKgDJ8vpPyWIfP148ek/etiwH3/O6j9m9LgWRvzqPy+3YkriAes/ExFHO6Xv6j8sCuXlKg3rP8fZZhpRK+s/OF7wNOVq6z8LsGv9E6XrP1O3oDFM0+s/pNTigxXK6z9+JtZlAsPrP72gAcyiy+s/6KMAT6Dl6z/h0C3D2rzrP6kduaWP6+s/5qp22xfi6z+Revg2u+nrPx3Y7gn1yes//BLRWE276z/DJEODp8vrPzr9rOWW0+s/OKTj0M9U7T+Hc48vaNHtP1pwwwHQ/u0/wmrxj0JR7j+2zdv803HuP1ILmCxAg+4/z6a8bfGb7j9hovBMZqnuP43C6SP8ru4/g1JfSnK+7j+xM0FHW9juP0a6Kji36+4/qrJL/Fv87j90IRCUSfruPxtY3gjd8O4/6hHXqq347j81+ZkZPvHuP0adVA8B8+4/7EckneL37j/SoX+TdvPuP0ofe0xf8+4/VEJbCWXy7j+y/pqJtPHuP9Yv5qwS8e4/RB64inam5D/kE4ucSPHkP2CNifRA5eQ/VM/hHaHL5T9dFh3O0gzmPzIdYcRBquY/WI4aV44a5z8RBNev21rnP35OWMM7o+c/V3zFV3zF5z9yr4JZUg7oP8nSDmTjfug/PIjvIL6D6D8RdVqXAK/oPwxmmqRNEek/aF4Pu/qT6T8R1bg2ePrpP7To+AhyDOo/V7PzVKlQ6j/bALa3I5PqP8uU4icboOo/Te07F+Tq6j9ydGiSf8HqP/4H5GEp7+o/Ia/yfEj/6D+yNzNpCxzpP1nPMVnPMek/WhfImXdk6T881z1JvHPpP11xo29niuk/enYyLbma6T97sK3p37HpP2A/NNsS0Ok/R2io9y/s6T+HwMtW1/bpP5YWcTCDI+o/BhLgnC8h6j8/OExvVTfqP+4MxCOdSeo/Xtk3mml46j/sDcK2jYjqP7V/8pJnnOo/7z7cAgqj6j/Ib9P/57LqP+YvM6Jkzeo/ou6sGerO6j/+lI1M9drqP/nCVgpjyuo/DpL7WS0r6j9Km3635DXrPx8ADkkWpuo/uGT8L9eR6z8ZCKtQ957rP2DfQLs7pes/EJ5d+UDp6z9iaBgf+EnsP/42oKxqJew/UkIFq5lp7D9L1QsJK8vsPwLH61sY1+w/mD4bfJUY7T+uVPHwSTrtP7CZY81SN+0/tytSaoVQ7T8HuM7CjUTtP8X9eIb1Mu0/P1o1p45D7T+QbcEEyFXtP7CAQse8Ve0/ANgXt09E7T99yFW4IFPtP1P0yyhPQ+0/\",\"dtype\":\"float64\",\"shape\":[192]},\"score_errn95\":{\"__ndarray__\":\"YbyXW15qhD83mxUglT6EP6TjVjSnIoQ/egk/W3Z+gz+hkn2X90+DPyGni5UxWYM/yDjWnvkigz+3V8b+XrCCP6sQ/SP1jII/tCQwnJgigj/E279c13yBP5MZxbC0cYE/6sViBDS9gD838IN551WAP96jb/mnKn8/Hlst8aiHfj8qbxpEFZl9Pz6hqemOonw/JDrU/oORfD/Z/zWnZvd8P6l5aKu4qXw/envGuChifD8An6bUVHF8P1xVcqClrnw/tfFHZpDvbz/efdJWmvluP8eWhMMOE24/HvVgdf+taz+ODjvul0RrP13RAjFaUms/uUE5MPHHaj9L7gKADpNqP3zY2gYzO2o/Wb1i+KQhaT8HXFxs5qdnP2usiuD8kWY/ugMy7vbXZT993WUhUA9lPx2EYV40J2U/FAU5yduhZD+sORxUwNZkPz3L9Yvo12Q/K7Gh7Z5rZD8A1qMTTYpkP8fHKEvidGQ/x2OT5b6uZD8FxZbPv8ZkP7vF21h/t2Q/NWaSgEXoaz9ZcqU5MP9rP6PZpqtbqWs/XEIZJPnKaj/uNZ+jiJBpP2BMDpcGo2k/3kr9uNkdaT+dUvQ8p+RoP85V7qKym2g/5I/0fXhXaD/N3PyrYk1nPyStC2aVJGc/oc0iBcejZj/eomBdBWJmP2A+xYlP12U/2WmTH9VDZT9ydYJq7mtlPwf+fg6hJGU/2x97mc0FZT/Q30HLnxBlP1O41pD/UmU/iCg0REgIZT9cLItEVBBlPxKAthfSa2U/XoZcAwvlWT9bPWy9iVJZP5NlQfwmF1k/1wH9MbuUVz8G1u7Qcz1XP1nEpmsOMlc/ZSDnr+xVVz/isiZ5oBtXP4egxcw/3FY/YDqjA+NVVj+j6P6e19ZVPzDi4QGxWlU/1mnvGzyIVT/8ShLO6ZpVP9xVbObFjVU//Us4IuxKVT/z7w+vmKRVP5cQCQ0qM1U/xEV7AE1OVT+OZxf/3DxVP3kXTERpkFU/Nx6MMCGjVT+p3MJf5YRVPyN56PwneVU/+CmZCEh/UD8hnKjZ9gpOP0NeIxzd4Uw/UVqDBdaeSj+Lgvvu4aRJPwrC/XeAGUk/JgFo5SdRSD9crpyUHeBHP+iwPIGCsEc/Lwr3kscoRz+u1YvdRD1GP8Q+t2Q4hkU/eiAqREHlRD+Q8tGpj/hEP6oFeIpFUkU/JefzlmsIRT9ubzk+tlFFP2bprwPUP0U/Qy3TCsgQRT9KF6vRNDtFPye6bh1qPEU/YfxrBV9FRT/YhRjvI01FP8QXNK3PU0U/imG10137nz96kvjPZhyfP8yWEBieiJ8/pTsu6p7Xnj+eSWPUyjSeP4o/3vicnZ0/0datB50qnT/j9Cvee+WcPxp6H94FrZw/EjSnb5ZinD+ZS7M5jeabP4XSXDXaPJs/Q52zr4rpmj+zaLb5yfKaP3RMtsbII5o/T5Iw3X9bmT/Ac3SfzKCYP/d4duaHqZg/poHpxxppmD9h+inv+vSXP7qblP7a/pc/8BgtthpGlz8kezGKqnCXPwW/sJsZ/ZY/7W0xEZqbhT8Jc1OB5Y2FP5dglwYdboU/VKW5C7cchT/QS6HKlgeFP4EAQseH64Q/xqKeaGn1hD/Le9wM386EP4hZQX5uqoQ//z0HB4F+hD8b7to5GT+EPx+Vy6HuJIQ/1RAg00EzhD8lxTI/QhuEP65+bv7A/oM/7tduyPSmgz8LN5e5xaWDP82jC/M+jYM/uc6VpH1+gz99De5zSG2DPxCoS8MDL4M/E2iWicM1gz/PPP0+6SqDP/MYEB3iHIM/NKFILzC2ZT/k1Lcy/O9jP6GBP09Q4WQ/8l/Ksms5Yz+IX9oC2ihjP7W3Vg0yGmM/lHhnMnmfYj/tf9F0kd1hP1D/HSqoJmI/uF3kgVuQYT+QyCwFtMNgP5z3hw9NjGA/hpLc09P5Xz8OPavsFF9fP4ag8vb2ZF8//8zuSkb2Xj/p+iz9vzZfP+22DrTqmV8/D9xeIdUxXz9sHOBcjM1eP0MslZLV514/MZ7JVSQqXz9pAChUcvVeP+P36luDMV8/\",\"dtype\":\"float64\",\"shape\":[192]},\"seed\":[\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\"],\"split\":[\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\"],\"stratifier\":[\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\"],\"stratum_key\":{\"__ndarray__\":\"AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/\",\"dtype\":\"float64\",\"shape\":[192]},\"tag\":[\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\"],\"task\":[\"coref-ontonotes-conll\",\"coref-ontonotes-conll\",\"coref-ontonotes-conll\",\"coref-ontonotes-conll\",\"coref-ontonotes-conll\",\"coref-ontonotes-conll\",\"coref-ontonotes-conll\",\"coref-ontonotes-conll\",\"coref-ontonotes-conll\",\"coref-ontonotes-conll\",\"coref-ontonotes-conll\",\"coref-ontonotes-conll\",\"coref-ontonotes-conll\",\"coref-ontonotes-conll\",\"coref-ontonotes-conll\",\"coref-ontonotes-conll\",\"coref-ontonotes-conll\",\"coref-ontonotes-conll\",\"coref-ontonotes-conll\",\"coref-ontonotes-conll\",\"coref-ontonotes-conll\",\"coref-ontonotes-conll\",\"coref-ontonotes-conll\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"dep-labeling-ewt\",\"dep-labeling-ewt\",\"dep-labeling-ewt\",\"dep-labeling-ewt\",\"dep-labeling-ewt\",\"dep-labeling-ewt\",\"dep-labeling-ewt\",\"dep-labeling-ewt\",\"dep-labeling-ewt\",\"dep-labeling-ewt\",\"dep-labeling-ewt\",\"dep-labeling-ewt\",\"dep-labeling-ewt\",\"dep-labeling-ewt\",\"dep-labeling-ewt\",\"dep-labeling-ewt\",\"dep-labeling-ewt\",\"dep-labeling-ewt\",\"dep-labeling-ewt\",\"dep-labeling-ewt\",\"dep-labeling-ewt\",\"dep-labeling-ewt\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"ner-ontonotes\",\"ner-ontonotes\",\"ner-ontonotes\",\"ner-ontonotes\",\"ner-ontonotes\",\"ner-ontonotes\",\"ner-ontonotes\",\"ner-ontonotes\",\"ner-ontonotes\",\"ner-ontonotes\",\"ner-ontonotes\",\"ner-ontonotes\",\"ner-ontonotes\",\"ner-ontonotes\",\"ner-ontonotes\",\"ner-ontonotes\",\"ner-ontonotes\",\"ner-ontonotes\",\"ner-ontonotes\",\"ner-ontonotes\",\"ner-ontonotes\",\"ner-ontonotes\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"nonterminal-ontonotes\",\"nonterminal-ontonotes\",\"nonterminal-ontonotes\",\"nonterminal-ontonotes\",\"nonterminal-ontonotes\",\"nonterminal-ontonotes\",\"nonterminal-ontonotes\",\"nonterminal-ontonotes\",\"nonterminal-ontonotes\",\"nonterminal-ontonotes\",\"nonterminal-ontonotes\",\"nonterminal-ontonotes\",\"nonterminal-ontonotes\",\"nonterminal-ontonotes\",\"nonterminal-ontonotes\",\"nonterminal-ontonotes\",\"nonterminal-ontonotes\",\"nonterminal-ontonotes\",\"nonterminal-ontonotes\",\"nonterminal-ontonotes\",\"nonterminal-ontonotes\",\"nonterminal-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"pos-ontonotes\",\"pos-ontonotes\",\"pos-ontonotes\",\"pos-ontonotes\",\"pos-ontonotes\",\"pos-ontonotes\",\"pos-ontonotes\",\"pos-ontonotes\",\"pos-ontonotes\",\"pos-ontonotes\",\"pos-ontonotes\",\"pos-ontonotes\",\"pos-ontonotes\",\"pos-ontonotes\",\"pos-ontonotes\",\"pos-ontonotes\",\"pos-ontonotes\",\"pos-ontonotes\",\"pos-ontonotes\",\"pos-ontonotes\",\"pos-ontonotes\",\"pos-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"rel-semeval\",\"rel-semeval\",\"rel-semeval\",\"rel-semeval\",\"rel-semeval\",\"rel-semeval\",\"rel-semeval\",\"rel-semeval\",\"rel-semeval\",\"rel-semeval\",\"rel-semeval\",\"rel-semeval\",\"rel-semeval\",\"rel-semeval\",\"rel-semeval\",\"rel-semeval\",\"rel-semeval\",\"rel-semeval\",\"rel-semeval\",\"rel-semeval\",\"rel-semeval\",\"rel-semeval\",\"rel-semeval\",\"spr1\",\"spr1\",\"spr1\",\"spr1\",\"spr1\",\"spr1\",\"spr1\",\"spr1\",\"spr1\",\"spr1\",\"spr1\",\"spr1\",\"spr1\",\"spr1\",\"spr1\",\"spr1\",\"spr1\",\"spr1\",\"spr1\",\"spr1\",\"spr1\",\"spr1\",\"spr1\",\"spr1\",\"srl-conll2012\",\"srl-conll2012\",\"srl-conll2012\",\"srl-conll2012\",\"srl-conll2012\",\"srl-conll2012\",\"srl-conll2012\",\"srl-conll2012\",\"srl-conll2012\",\"srl-conll2012\",\"srl-conll2012\",\"srl-conll2012\",\"srl-conll2012\",\"srl-conll2012\",\"srl-conll2012\",\"srl-conll2012\",\"srl-conll2012\",\"srl-conll2012\",\"srl-conll2012\",\"srl-conll2012\",\"srl-conll2012\",\"srl-conll2012\",\"srl-conll2012\",\"srl-conll2012\"],\"tn_count\":{\"__ndarray__\":\"AAAAAMAc00AAAAAAADjTQAAAAADALdNAAAAAAIA200AAAAAAQDnTQAAAAABAQNNAAAAAAEA+00AAAAAAADvTQAAAAACAR9NAAAAAAEBH00AAAAAAwE7TQAAAAABAWdNAAAAAAEBe00AAAAAAAG3TQAAAAADAfdNAAAAAAACF00AAAAAAAJTTQAAAAAAAndNAAAAAAACW00AAAAAAwJPTQAAAAACAm9NAAAAAAMCW00AAAAAAwJnTQAAAAADAltNAAAAAAE2/MkEAAAAAiL8yQQAAAADcvzJBAAAAAJ/AMkEAAAAAvsAyQQAAAADSwDJBAAAAAAjBMkEAAAAAE8EyQQAAAAA6wTJBAAAAAI7BMkEAAAAA+cEyQQAAAAA3wjJBAAAAAITCMkEAAAAAvsIyQQAAAAC5wjJBAAAAAN7CMkEAAAAAv8IyQQAAAADEwjJBAAAAAPLCMkEAAAAA3MIyQQAAAADnwjJBAAAAAMjCMkEAAAAAxsIyQQAAAADPwjJBAAAAAHRLFkEAAAAAgEsWQQAAAACISxZBAAAAAIhMFkEAAAAA0E0WQQAAAAC4TRZBAAAAAHxOFkEAAAAAxE4WQQAAAABoTxZBAAAAAHhPFkEAAAAAeFAWQQAAAADcUBZBAAAAAIBRFkEAAAAAcFEWQQAAAADwURZBAAAAAKBSFkEAAAAAoFIWQQAAAAC8UhZBAAAAANRSFkEAAAAA8FIWQQAAAADEUhZBAAAAABhTFkEAAAAAHFMWQQAAAADwUhZBAAAAgP0VXEEAAABAcBdcQQAAAIAvF1xBAAAAQI0YXEEAAABAshhcQQAAAABpGVxBAAAAgDwYXEEAAACAABhcQQAAAIBiF1xBAAAAAOEXXEEAAACAtBhcQQAAAMCbF1xBAAAAwO0ZXEEAAABAPRpcQQAAAIDmG1xBAAAAgKMaXEEAAAAAfhlcQQAAAMCQGVxBAAAAQPQZXEEAAABAHxpcQQAAAEB5G1xBAAAAANQYXEEAAADA/BlcQQAAAMA3G1xBAAAAoDH1aUEAAABgI/dpQQAAACC892lBAAAAQLX4aUEAAADAOPlpQQAAAMCG+WlBAAAAoNL5aUEAAADA//lpQQAAAEAR+mlBAAAAQFj6aUEAAAAgyPppQQAAAIAW+2lBAAAAQD37aUEAAABgSftpQQAAAGA7+2lBAAAAwEP7aUEAAAAgIvtpQQAAAMAw+2lBAAAAYDr7aUEAAADgM/tpQQAAAGAw+2lBAAAAIDL7aUEAAADAJPtpQQAAAIAb+2lBAAAAAIAf00AAAAAAQCjTQAAAAADAI9NAAAAAAIAg00AAAAAAQCbTQAAAAACAJdNAAAAAAAAl00AAAAAAwCTTQAAAAAAAI9NAAAAAAAAl00AAAAAAwCbTQAAAAAAAKNNAAAAAAMAq00AAAAAAgCjTQAAAAABAK9NAAAAAAAAs00AAAAAAQC3TQAAAAABALNNAAAAAAAAr00AAAAAAgCvTQAAAAABAKtNAAAAAAMAs00AAAAAAgC3TQAAAAADALtNAAAAAAACgx0AAAAAAgM7HQAAAAAAAyMdAAAAAAICzx0AAAAAAgLTHQAAAAACAu8dAAAAAAAD7x0AAAAAAgOzHQAAAAACA+8dAAAAAAID1x0AAAAAAgLPHQAAAAAAA7cdAAAAAAID+x0AAAAAAABLIQAAAAACAEchAAAAAAAD+x0AAAAAAACfIQAAAAACAN8hAAAAAAIAuyEAAAAAAgELIQAAAAAAAIchAAAAAAIAvyEAAAAAAgEHIQAAAAAAABMhAAAAAAOkeQUEAAAAAkyFBQQAAAICJIEFBAAAAANAiQUEAAACAsSJBQQAAAIDUIkFBAAAAAC4jQUEAAAAA/SNBQQAAAAC6I0FBAAAAAJEkQUEAAAAALSVBQQAAAAD+JUFBAAAAgFcmQUEAAAAAhyZBQQAAAACcJkFBAAAAAKYmQUEAAAAAeyZBQQAAAIAnJkFBAAAAAJomQUEAAACA4CZBQQAAAACIJkFBAAAAgKgmQUEAAACAgCZBQQAAAICeJkFB\",\"dtype\":\"float64\",\"shape\":[192]},\"total_count\":{\"__ndarray__\":\"AAAAAEC32UAAAAAAQLfZQAAAAABAt9lAAAAAAEC32UAAAAAAQLfZQAAAAABAt9lAAAAAAEC32UAAAAAAQLfZQAAAAABAt9lAAAAAAEC32UAAAAAAQLfZQAAAAABAt9lAAAAAAEC32UAAAAAAQLfZQAAAAABAt9lAAAAAAEC32UAAAAAAQLfZQAAAAABAt9lAAAAAAEC32UAAAAAAQLfZQAAAAABAt9lAAAAAAEC32UAAAAAAQLfZQAAAAABAt9lAAAAAAEwoM0EAAAAATCgzQQAAAABMKDNBAAAAAEwoM0EAAAAATCgzQQAAAABMKDNBAAAAAEwoM0EAAAAATCgzQQAAAABMKDNBAAAAAEwoM0EAAAAATCgzQQAAAABMKDNBAAAAAEwoM0EAAAAATCgzQQAAAABMKDNBAAAAAEwoM0EAAAAATCgzQQAAAABMKDNBAAAAAEwoM0EAAAAATCgzQQAAAABMKDNBAAAAAEwoM0EAAAAATCgzQQAAAABMKDNBAAAAAJiaF0EAAAAAmJoXQQAAAACYmhdBAAAAAJiaF0EAAAAAmJoXQQAAAACYmhdBAAAAAJiaF0EAAAAAmJoXQQAAAACYmhdBAAAAAJiaF0EAAAAAmJoXQQAAAACYmhdBAAAAAJiaF0EAAAAAmJoXQQAAAACYmhdBAAAAAJiaF0EAAAAAmJoXQQAAAACYmhdBAAAAAJiaF0EAAAAAmJoXQQAAAACYmhdBAAAAAJiaF0EAAAAAmJoXQQAAAACYmhdBAAAAgJkyXUEAAACAmTJdQQAAAICZMl1BAAAAgJkyXUEAAACAmTJdQQAAAICZMl1BAAAAgJkyXUEAAACAmTJdQQAAAICZMl1BAAAAgJkyXUEAAACAmTJdQQAAAICZMl1BAAAAgJkyXUEAAACAmTJdQQAAAICZMl1BAAAAgJkyXUEAAACAmTJdQQAAAICZMl1BAAAAgJkyXUEAAACAmTJdQQAAAICZMl1BAAAAgJkyXUEAAACAmTJdQQAAAICZMl1BAAAAAC6NakEAAAAALo1qQQAAAAAujWpBAAAAAC6NakEAAAAALo1qQQAAAAAujWpBAAAAAC6NakEAAAAALo1qQQAAAAAujWpBAAAAAC6NakEAAAAALo1qQQAAAAAujWpBAAAAAC6NakEAAAAALo1qQQAAAAAujWpBAAAAAC6NakEAAAAALo1qQQAAAAAujWpBAAAAAC6NakEAAAAALo1qQQAAAAAujWpBAAAAAC6NakEAAAAALo1qQQAAAAAujWpBAAAAAIAy1EAAAAAAgDLUQAAAAACAMtRAAAAAAIAy1EAAAAAAgDLUQAAAAACAMtRAAAAAAIAy1EAAAAAAgDLUQAAAAACAMtRAAAAAAIAy1EAAAAAAgDLUQAAAAACAMtRAAAAAAIAy1EAAAAAAgDLUQAAAAACAMtRAAAAAAIAy1EAAAAAAgDLUQAAAAACAMtRAAAAAAIAy1EAAAAAAgDLUQAAAAACAMtRAAAAAAIAy1EAAAAAAgDLUQAAAAACAMtRAAAAAAIDT0kAAAAAAgNPSQAAAAACA09JAAAAAAIDT0kAAAAAAgNPSQAAAAACA09JAAAAAAIDT0kAAAAAAgNPSQAAAAACA09JAAAAAAIDT0kAAAAAAgNPSQAAAAACA09JAAAAAAIDT0kAAAAAAgNPSQAAAAACA09JAAAAAAIDT0kAAAAAAgNPSQAAAAACA09JAAAAAAIDT0kAAAAAAgNPSQAAAAACA09JAAAAAAIDT0kAAAAAAgNPSQAAAAACA09JAAAAAAIjOQUEAAAAAiM5BQQAAAACIzkFBAAAAAIjOQUEAAAAAiM5BQQAAAACIzkFBAAAAAIjOQUEAAAAAiM5BQQAAAACIzkFBAAAAAIjOQUEAAAAAiM5BQQAAAACIzkFBAAAAAIjOQUEAAAAAiM5BQQAAAACIzkFBAAAAAIjOQUEAAAAAiM5BQQAAAACIzkFBAAAAAIjOQUEAAAAAiM5BQQAAAACIzkFBAAAAAIjOQUEAAAAAiM5BQQAAAACIzkFB\",\"dtype\":\"float64\",\"shape\":[192]},\"tp_count\":{\"__ndarray__\":\"AAAAAABNskAAAAAAAC6yQAAAAAAAXrJAAAAAAADEskAAAAAAAN+yQAAAAAAAx7JAAAAAAADzskAAAAAAAEmzQAAAAAAARLNAAAAAAACKs0AAAAAAAN+zQAAAAAAAzrNAAAAAAAArtEAAAAAAAEK0QAAAAAAAf7RAAAAAAACWtEAAAAAAAKi0QAAAAAAAyrRAAAAAAADjtEAAAAAAANG0QAAAAAAAzbRAAAAAAADstEAAAAAAAOC0QAAAAAAA2rRAAAAAAEC01EAAAAAAQAXVQAAAAACAQdVAAAAAAEDf1UAAAAAAQPnVQAAAAACA69VAAAAAAAAH1kAAAAAAgBXWQAAAAAAAJNZAAAAAAMBh1kAAAAAAwK/WQAAAAACA6tZAAAAAAAAB10AAAAAAQCHXQAAAAADAHNdAAAAAAMAx10AAAAAAADDXQAAAAADALddAAAAAAAA410AAAAAAwDjXQAAAAAAAOtdAAAAAAAA310AAAAAAgDHXQAAAAAAAMtdAAAAAAEBV0kAAAAAAQE/SQAAAAABAYdJAAAAAAAB80kAAAAAAgKHSQAAAAADAn9JAAAAAAECq0kAAAAAAgK/SQAAAAAAAsNJAAAAAAMC70kAAAAAAwNfSQAAAAADA1tJAAAAAAMDf0kAAAAAAwOzSQAAAAADA+dJAAAAAAIAD00AAAAAAwPzSQAAAAABABtNAAAAAAEAJ00AAAAAAAAXTQAAAAADA/dJAAAAAAMAC00AAAAAAAAHTQAAAAABA9dJAAAAAALB4B0EAAAAASOUHQQAAAACAJghBAAAAAAhpCUEAAAAAsLAJQQAAAABAqQlBAAAAAKCmCUEAAAAA0NwJQQAAAAB4HQpBAAAAAIh8CkEAAAAAYMsKQQAAAACgNQtBAAAAALjsCkEAAAAAANkKQQAAAADwvgpBAAAAAHgKC0EAAAAAyOAKQQAAAABALwtBAAAAAFAVC0EAAAAAUB4LQQAAAACQxgpBAAAAAGDuCkEAAAAA+O0KQQAAAABI3QpBAAAAAMgSEEEAAAAAWFwQQQAAAABkehBBAAAAAGy0EEEAAAAAvMcQQQAAAAA00RBBAAAAAJjiEEEAAAAAqOsQQQAAAACQ7xBBAAAAAMj3EEEAAAAAYAYRQQAAAADkERFBAAAAACgfEUEAAAAAhBsRQQAAAAAUExFBAAAAAHQaEUEAAAAAcBYRQQAAAACcFhFBAAAAALQaEUEAAAAAvBYRQQAAAAAMFxFBAAAAAMwVEUEAAAAAoBYRQQAAAAAIFxFBAAAAAABggEAAAAAAADCAQAAAAAAAaIBAAAAAAACwgUAAAAAAAKCBQAAAAAAAcIJAAAAAAAAIg0AAAAAAAGCDQAAAAAAA4INAAAAAAADog0AAAAAAACiEQAAAAAAAqIRAAAAAAAB4hEAAAAAAAOCEQAAAAAAAMIVAAAAAAADYhUAAAAAAAFCGQAAAAAAAgIZAAAAAAAAAh0AAAAAAAFiHQAAAAAAAiIdAAAAAAADAh0AAAAAAAHCHQAAAAAAAmIdAAAAAAAD7sUAAAAAAAOGxQAAAAAAAA7JAAAAAAABaskAAAAAAAGuyQAAAAAAAfbJAAAAAAAA8skAAAAAAAGuyQAAAAAAAe7JAAAAAAAClskAAAAAAAAyzQAAAAAAA9LJAAAAAAADZskAAAAAAANmyQAAAAAAA8LJAAAAAAABFs0AAAAAAAB+zQAAAAAAAILNAAAAAAAA1s0AAAAAAACyzQAAAAAAAfbNAAAAAAABqs0AAAAAAAF+zQAAAAAAAo7NAAAAAAMBe7kAAAAAAIPvvQAAAAADgCO9AAAAAAIA+8EAAAAAAAE/wQAAAAAAwUvBAAAAAAMCQ8EAAAAAAIOPwQAAAAADAwvBAAAAAAFD28EAAAAAAQFDxQAAAAADgR/FAAAAAAICG8UAAAAAA4KbxQAAAAABgofFAAAAAAGC88UAAAAAAkLPxQAAAAADAqPFAAAAAADCv8UAAAAAAELzxQAAAAABgxfFAAAAAAICu8UAAAAAAQMPxQAAAAABwrvFA\",\"dtype\":\"float64\",\"shape\":[192]},\"true_pos_count\":{\"__ndarray__\":\"AAAAAACutkAAAAAAAK62QAAAAAAArrZAAAAAAACutkAAAAAAAK62QAAAAAAArrZAAAAAAACutkAAAAAAAK62QAAAAAAArrZAAAAAAACutkAAAAAAAK62QAAAAAAArrZAAAAAAACutkAAAAAAAK62QAAAAAAArrZAAAAAAACutkAAAAAAAK62QAAAAAAArrZAAAAAAACutkAAAAAAAK62QAAAAAAArrZAAAAAAACutkAAAAAAAK62QAAAAAAArrZAAAAAAICF2EAAAAAAgIXYQAAAAACAhdhAAAAAAICF2EAAAAAAgIXYQAAAAACAhdhAAAAAAICF2EAAAAAAgIXYQAAAAACAhdhAAAAAAICF2EAAAAAAgIXYQAAAAACAhdhAAAAAAICF2EAAAAAAgIXYQAAAAACAhdhAAAAAAICF2EAAAAAAgIXYQAAAAACAhdhAAAAAAICF2EAAAAAAgIXYQAAAAACAhdhAAAAAAICF2EAAAAAAgIXYQAAAAACAhdhAAAAAAIDg00AAAAAAgODTQAAAAACA4NNAAAAAAIDg00AAAAAAgODTQAAAAACA4NNAAAAAAIDg00AAAAAAgODTQAAAAACA4NNAAAAAAIDg00AAAAAAgODTQAAAAACA4NNAAAAAAIDg00AAAAAAgODTQAAAAACA4NNAAAAAAIDg00AAAAAAgODTQAAAAACA4NNAAAAAAIDg00AAAAAAgODTQAAAAACA4NNAAAAAAIDg00AAAAAAgODTQAAAAACA4NNAAAAAAOgkD0EAAAAA6CQPQQAAAADoJA9BAAAAAOgkD0EAAAAA6CQPQQAAAADoJA9BAAAAAOgkD0EAAAAA6CQPQQAAAADoJA9BAAAAAOgkD0EAAAAA6CQPQQAAAADoJA9BAAAAAOgkD0EAAAAA6CQPQQAAAADoJA9BAAAAAOgkD0EAAAAA6CQPQQAAAADoJA9BAAAAAOgkD0EAAAAA6CQPQQAAAADoJA9BAAAAAOgkD0EAAAAA6CQPQQAAAADoJA9BAAAAAHSzEUEAAAAAdLMRQQAAAAB0sxFBAAAAAHSzEUEAAAAAdLMRQQAAAAB0sxFBAAAAAHSzEUEAAAAAdLMRQQAAAAB0sxFBAAAAAHSzEUEAAAAAdLMRQQAAAAB0sxFBAAAAAHSzEUEAAAAAdLMRQQAAAAB0sxFBAAAAAHSzEUEAAAAAdLMRQQAAAAB0sxFBAAAAAHSzEUEAAAAAdLMRQQAAAAB0sxFBAAAAAHSzEUEAAAAAdLMRQQAAAAB0sxFBAAAAAAAIjkAAAAAAAAiOQAAAAAAACI5AAAAAAAAIjkAAAAAAAAiOQAAAAAAACI5AAAAAAAAIjkAAAAAAAAiOQAAAAAAACI5AAAAAAAAIjkAAAAAAAAiOQAAAAAAACI5AAAAAAAAIjkAAAAAAAAiOQAAAAAAACI5AAAAAAAAIjkAAAAAAAAiOQAAAAAAACI5AAAAAAAAIjkAAAAAAAAiOQAAAAAAACI5AAAAAAAAIjkAAAAAAAAiOQAAAAAAACI5AAAAAAABGt0AAAAAAAEa3QAAAAAAARrdAAAAAAABGt0AAAAAAAEa3QAAAAAAARrdAAAAAAABGt0AAAAAAAEa3QAAAAAAARrdAAAAAAABGt0AAAAAAAEa3QAAAAAAARrdAAAAAAABGt0AAAAAAAEa3QAAAAAAARrdAAAAAAABGt0AAAAAAAEa3QAAAAAAARrdAAAAAAABGt0AAAAAAAEa3QAAAAAAARrdAAAAAAABGt0AAAAAAAEa3QAAAAAAARrdAAAAAAKDF80AAAAAAoMXzQAAAAACgxfNAAAAAAKDF80AAAAAAoMXzQAAAAACgxfNAAAAAAKDF80AAAAAAoMXzQAAAAACgxfNAAAAAAKDF80AAAAAAoMXzQAAAAACgxfNAAAAAAKDF80AAAAAAoMXzQAAAAACgxfNAAAAAAKDF80AAAAAAoMXzQAAAAACgxfNAAAAAAKDF80AAAAAAoMXzQAAAAACgxfNAAAAAAKDF80AAAAAAoMXzQAAAAACgxfNA\",\"dtype\":\"float64\",\"shape\":[192]}},\"selected\":{\"id\":\"3384\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"3385\",\"type\":\"UnionRenderers\"}},\"id\":\"3255\",\"type\":\"ColumnDataSource\"},{\"attributes\":{},\"id\":\"3386\",\"type\":\"Selection\"},{\"attributes\":{\"dimension\":1,\"plot\":{\"id\":\"3199\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"ticker\":{\"id\":\"3213\",\"type\":\"CategoricalTicker\"}},\"id\":\"3215\",\"type\":\"Grid\"},{\"attributes\":{\"range\":{\"id\":\"3198\",\"type\":\"FactorRange\"}},\"id\":\"3233\",\"type\":\"Dodge\"},{\"attributes\":{},\"id\":\"3385\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"callback\":null,\"renderers\":[{\"id\":\"3239\",\"type\":\"GlyphRenderer\"},{\"id\":\"3245\",\"type\":\"GlyphRenderer\"}],\"tooltips\":[[\"task\",\"@_display_name\"],[\"experiment\",\"@exp_type\"],[\"layer\",\"@layer_num\"],[\"weight\",\"@layer_weight{0.0%}\"]]},\"id\":\"3196\",\"type\":\"HoverTool\"},{\"attributes\":{\"callback\":null,\"data\":{\"_bar_center\":[\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\"],\"_bar_height\":[0.04494346976280213,0.04006913993507624,0.09287066906690598,0.0376878110691905,0.12816421128809452,0.09434745647013187,0.09976273588836193,0.06169388685375452,0.1017415925860405,0.04303781222552061,0.02665954409167171,0.092449951171875,0.030033160373568537,0.09519200026988983,0.0938491590321064,0.09799955897033215,0.05106540396809578,0.09109024219214917,0.044170017912983896,0.022351319622248414,0.08779376037418843,0.028858571592718364,0.07931437566876412,0.09353651739656926,0.09733275510370731,0.04365954492241145,0.0903110269457102,0.041819173190742735,0.025936662778258325,0.08510068506002427,0.029954698216170073,0.07533357851207256,0.09359927102923393,0.09677075855433942,0.04482156839221716,0.0901101429015398,0.03978559691458941,0.03480054046958685,0.07972162552177907,0.03098505372181535,0.06407867074012757,0.09469664990901948,0.09599633105099202,0.05054207649081946,0.09214825294911862,0.039017561450600625,0.038755980692803865,0.08183977436274291,0.030400400888174774,0.07222927026450635,0.09456777311861515,0.09492500312626362,0.054807588458061225,0.09116704724729062,0.03884538123384118,0.03700121752917767,0.08249406069517136,0.027693530637770893,0.0798001253977418,0.09401903338730336,0.09416523054242135,0.054352310299873356,0.08928837105631829,0.039486486185342076,0.02885133465752006,0.08797116838395597,0.030837863311171533,0.0809585077688098,0.09326150380074978,0.09388232119381429,0.04014560049399734,0.08832156881690026,0.03723419001325965,0.022521498240530492,0.08459334522485734,0.026859324239194394,0.07777618244290352,0.09274786747992039,0.09313415586948395,0.037022236827760936,0.08767789900302887,0.042273543588817124,0.018642216827720406,0.08229774814099074,0.03603771440684796,0.10015535093843937,0.09161568693816663,0.09128147028386593,0.03910883283242583,0.08522950150072575,0.04314245861023665,0.031788645219057804,0.07591128610074521,0.08341848738491536,0.11223619468510151,0.09220453910529613,0.09183554090559483,0.048697145842015746,0.0853905949741602,0.05216716825962067,0.11127796210348607,0.08471080586314202,0.24229259043931964,0.24783563017845156,0.09807938151061535,0.09389873631298543,0.08801243752241135,0.09033758081495763,0.06673061773180962,0.2567683316767216,0.08984680697321892,0.40822096019983295,0.2583534970879555,0.10338723845779896,0.09994269870221616,0.12581427432596684,0.09767241328954697,0.0768482705578208,0.4794349774718285,0.10167832598090172,0.5156459659337997,0.28137193992733955,0.10756293497979642,0.10925409458577634,0.32394714653491974,0.10553485304117204,0.0860912248492241,0.3546902909874916,0.12427419014275075,0.2829314567148686,0.1633545655757189,0.11223207078874112,0.11903460882604124,0.35821877717971806,0.11251056455075742,0.11384665668010713,0.22998050674796106,0.14578848704695702,0.22092887610197068,0.10071831308305264,0.12188248112797738,0.12420923374593258,0.2813253901898861,0.12405379302799703,0.2083232916891575,0.46487810611724856,0.16749810576438906,0.26806456893682484,0.10851157195866108,0.13009082525968552,0.12688109613955023,0.2898755148053169,0.13753882348537447,0.2577830716967583,0.17829358130693437,0.16354098580777646,0.12527223341166974,0.08917633183300495,0.1320855036377907,0.12739758901298048,0.19218101352453232,0.14197779558598997,0.35319715887308123,0.06741776447743178,0.15761889964342118,0.04084996450692416,0.07334743961691857,0.13149371445178987,0.12683158926665783,0.14120552055537702,0.14144478701055052,0.3369572952389717,0.04757114611566067,0.16487951204180717,0.03264276450499892,0.07273645419627428,0.13116803728044035,0.127137703076005,0.089138925075531,0.14031972773373128,0.3319104708731175,0.039260345790535216,0.15436116233468056,0.03534103492274881,0.06885472107678653,0.12991811446845533,0.12614560425281526,0.06290892250835896,0.13668489530682565,0.13514871373772622,0.02999556250870228,0.12364344522356988,0.03050988279283047,0.05796121247112752,0.12565156146883966,0.1222495883703232,0.05130967944860459,0.1297759607434273,0.09033160619437695,0.03306763647124172,0.10747762061655522,0.03593307808041573,0.06231307480484247,0.12103274725377561,0.12066990472376347,0.05398421231657267,0.12235910296440125,0.07643184754997492,0.0395142118446529,0.09810982793569566,0.03995051253587008,0.06900277398526669,0.11493384651839735,0.11653186641633512,0.0593707200139761,0.1144467942416668,0.06047666352242232,0.04047167748212815,0.08352814782410861,0.028649495076388122,0.08122366424649954,0.11203573308885098,0.11272982507944108,0.05679134856909514,0.11286671832203866],\"_display_name\":[\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\"],\"_formatted_entropy\":[\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\"],\"_formatted_kl_unif\":[\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\"],\"checkpoint\":[\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\"],\"display_col\":[\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\"],\"exp_name\":[\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\"],\"exp_type\":[\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\"],\"gamma\":{\"__ndarray__\":\"AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/\",\"dtype\":\"float64\",\"shape\":[225]},\"index\":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224],\"label\":[\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\"],\"layer_num\":[0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8,8,9,9,9,9,9,9,9,9,9,10,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,12,13,13,13,13,13,13,13,13,13,14,14,14,14,14,14,14,14,14,15,15,15,15,15,15,15,15,15,16,16,16,16,16,16,16,16,16,17,17,17,17,17,17,17,17,17,18,18,18,18,18,18,18,18,18,19,19,19,19,19,19,19,19,19,20,20,20,20,20,20,20,20,20,21,21,21,21,21,21,21,21,21,22,22,22,22,22,22,22,22,22,23,23,23,23,23,23,23,23,23,24,24,24,24,24,24,24,24,24],\"layer_weight\":[0.016645729541778564,0.014840422198176384,0.034396544098854065,0.01395844854414463,0.04746822640299797,0.03494350239634514,0.03694916144013405,0.022849587723612785,0.03768207132816315,0.015939930453896523,0.009873905219137669,0.03424072265625,0.01112339273095131,0.03525629639625549,0.03475894778966904,0.03629613295197487,0.018913112580776215,0.03373712673783302,0.01635926589369774,0.00827826652675867,0.03251620754599571,0.01068835984915495,0.029375694692134857,0.034643154591321945,0.036049168556928635,0.01617020182311535,0.03344852849841118,0.015488582663238049,0.009606171399354935,0.03151877224445343,0.011094332672655582,0.02790132537484169,0.03466639667749405,0.035841021686792374,0.016600580886006355,0.0333741270005703,0.014735406264662743,0.012889089062809944,0.02952652797102928,0.011475945822894573,0.02373284101486206,0.03507283329963684,0.0355541966855526,0.01871928758919239,0.034128982573747635,0.014450948685407639,0.014354066923260689,0.03031102754175663,0.011259407736361027,0.026751581579446793,0.03502510115504265,0.03515740856528282,0.02029910683631897,0.03376557305455208,0.014387178234755993,0.013704154640436172,0.030553355813026428,0.010256863199174404,0.029555601999163628,0.03482186421751976,0.034876011312007904,0.02013048529624939,0.03306976705789566,0.014624624513089657,0.010685679502785206,0.032581914216279984,0.011421430855989456,0.02998463250696659,0.0345412977039814,0.034771230071783066,0.014868740923702717,0.0327116921544075,0.013790440745651722,0.008341295644640923,0.03133086860179901,0.009947897866368294,0.028805993497371674,0.03435106202960014,0.03449413180351257,0.013711939565837383,0.03247329592704773,0.015656867995858192,0.006904524751007557,0.030480647459626198,0.013347301632165909,0.03709457442164421,0.03393173590302467,0.03380795195698738,0.014484752900898457,0.03156648203730583,0.01597868837416172,0.01177357230335474,0.02811529114842415,0.030895736068487167,0.04156896099448204,0.03414982929825783,0.034013163298368454,0.018035979941487312,0.031626146286726,0.019321173429489136,0.04121406003832817,0.03137437254190445,0.08973799645900726,0.09179097414016724,0.03632569685578346,0.034777309745550156,0.03259719908237457,0.03345836326479912,0.024715043604373932,0.09509938210248947,0.033276595175266266,0.15119294822216034,0.09568648040294647,0.0382915697991848,0.03701581433415413,0.04659787937998772,0.036174967885017395,0.028462322428822517,0.17756851017475128,0.03765863925218582,0.1909799873828888,0.10421182960271835,0.03983812406659126,0.040464479476213455,0.11998042464256287,0.03908698260784149,0.03188563883304596,0.1313667744398117,0.04602747783064842,0.10478942841291428,0.060501690953969955,0.04156743362545967,0.044086892157793045,0.13267362117767334,0.041670579463243484,0.04216542840003967,0.0851779654622078,0.05399573594331741,0.08182550966739655,0.037303078919649124,0.045141659677028656,0.046003419905900955,0.10419458895921707,0.045945849269628525,0.07715677469968796,0.17217707633972168,0.062036335468292236,0.09928317368030548,0.0401894710958004,0.04818178713321686,0.04699299857020378,0.10736130177974701,0.05094030499458313,0.0954752117395401,0.06603465974330902,0.06057073548436165,0.046397123485803604,0.03302827104926109,0.04892055690288544,0.0471842922270298,0.07117815315723419,0.052584368735551834,0.13081376254558563,0.024969542399048805,0.05837737023830414,0.015129616484045982,0.027165718376636505,0.04870137572288513,0.04697466269135475,0.05229834094643593,0.05238695815205574,0.12479899823665619,0.017618943005800247,0.061066485941410065,0.01208991277962923,0.026939427480101585,0.048580754548311234,0.04708803817629814,0.03301441669464111,0.05197026953101158,0.12292980402708054,0.014540868811309338,0.0571708008646965,0.013089272193610668,0.02550174854695797,0.04811782017350197,0.04672059416770935,0.023299600929021835,0.05062403529882431,0.05005507916212082,0.011109467595815659,0.045793868601322174,0.01129995658993721,0.021467115730047226,0.0465376153588295,0.04527762532234192,0.01900358498096466,0.048065170645713806,0.03345615044236183,0.01224727276712656,0.03980652615427971,0.01330854743719101,0.0230789165943861,0.044826943427324295,0.04469255730509758,0.019994152709841728,0.04531818628311157,0.028308091685175896,0.014634893275797367,0.03633697330951691,0.014796486124396324,0.02555658295750618,0.04256809130311012,0.04315995052456856,0.021989155560731888,0.0423877015709877,0.02239876426756382,0.014989510178565979,0.03093635104596615,0.01061092410236597,0.030082838609814644,0.041494715958833694,0.041751787066459656,0.02103383280336857,0.04180248826742172],\"run\":[\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\"],\"scalar_set\":[\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\"],\"tag\":[\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\"],\"task\":[\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\"],\"weight_entropy\":[4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481],\"weight_exp_layer\":{\"__ndarray__\":\"AABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipA\",\"dtype\":\"float64\",\"shape\":[225]},\"weight_exp_layer_oneplus\":{\"__ndarray__\":\"SG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytA\",\"dtype\":\"float64\",\"shape\":[225]},\"weight_kl_unif\":{\"__ndarray__\":\"w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/\",\"dtype\":\"float64\",\"shape\":[225]}},\"selected\":{\"id\":\"3380\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"3381\",\"type\":\"UnionRenderers\"}},\"id\":\"3241\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"source\":{\"id\":\"3248\",\"type\":\"ColumnDataSource\"}},\"id\":\"3254\",\"type\":\"CDSView\"},{\"attributes\":{\"callback\":null,\"renderers\":[{\"id\":\"3253\",\"type\":\"GlyphRenderer\"},{\"id\":\"3259\",\"type\":\"GlyphRenderer\"}],\"tooltips\":[[\"task\",\"@_display_name\"],[\"experiment\",\"@exp_type\"],[\"layer\",\"@layer_num\"],[\"score\",\"@score{0.0%} (\\u0394 @delta_score{0.0%})\"],[\"headroom fraction\",\"@headroom_frac{0.0%}\"]]},\"id\":\"3197\",\"type\":\"HoverTool\"},{\"attributes\":{},\"id\":\"3384\",\"type\":\"Selection\"},{\"attributes\":{\"data_source\":{\"id\":\"3248\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"3250\",\"type\":\"Rect\"},\"hover_glyph\":{\"id\":\"3252\",\"type\":\"Rect\"},\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"3251\",\"type\":\"Rect\"},\"selection_glyph\":null,\"view\":{\"id\":\"3254\",\"type\":\"CDSView\"}},\"id\":\"3253\",\"type\":\"GlyphRenderer\"},{\"attributes\":{},\"id\":\"3383\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"callback\":null,\"data\":{\"_bar_center\":[\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\"],\"_bar_height\":[0.04494346976280213,0.04006913993507624,0.09287066906690598,0.0376878110691905,0.12816421128809452,0.09434745647013187,0.09976273588836193,0.06169388685375452,0.1017415925860405,0.04303781222552061,0.02665954409167171,0.092449951171875,0.030033160373568537,0.09519200026988983,0.0938491590321064,0.09799955897033215,0.05106540396809578,0.09109024219214917,0.044170017912983896,0.022351319622248414,0.08779376037418843,0.028858571592718364,0.07931437566876412,0.09353651739656926,0.09733275510370731,0.04365954492241145,0.0903110269457102,0.041819173190742735,0.025936662778258325,0.08510068506002427,0.029954698216170073,0.07533357851207256,0.09359927102923393,0.09677075855433942,0.04482156839221716,0.0901101429015398,0.03978559691458941,0.03480054046958685,0.07972162552177907,0.03098505372181535,0.06407867074012757,0.09469664990901948,0.09599633105099202,0.05054207649081946,0.09214825294911862,0.039017561450600625,0.038755980692803865,0.08183977436274291,0.030400400888174774,0.07222927026450635,0.09456777311861515,0.09492500312626362,0.054807588458061225,0.09116704724729062,0.03884538123384118,0.03700121752917767,0.08249406069517136,0.027693530637770893,0.0798001253977418,0.09401903338730336,0.09416523054242135,0.054352310299873356,0.08928837105631829,0.039486486185342076,0.02885133465752006,0.08797116838395597,0.030837863311171533,0.0809585077688098,0.09326150380074978,0.09388232119381429,0.04014560049399734,0.08832156881690026,0.03723419001325965,0.022521498240530492,0.08459334522485734,0.026859324239194394,0.07777618244290352,0.09274786747992039,0.09313415586948395,0.037022236827760936,0.08767789900302887,0.042273543588817124,0.018642216827720406,0.08229774814099074,0.03603771440684796,0.10015535093843937,0.09161568693816663,0.09128147028386593,0.03910883283242583,0.08522950150072575,0.04314245861023665,0.031788645219057804,0.07591128610074521,0.08341848738491536,0.11223619468510151,0.09220453910529613,0.09183554090559483,0.048697145842015746,0.0853905949741602,0.05216716825962067,0.11127796210348607,0.08471080586314202,0.24229259043931964,0.24783563017845156,0.09807938151061535,0.09389873631298543,0.08801243752241135,0.09033758081495763,0.06673061773180962,0.2567683316767216,0.08984680697321892,0.40822096019983295,0.2583534970879555,0.10338723845779896,0.09994269870221616,0.12581427432596684,0.09767241328954697,0.0768482705578208,0.4794349774718285,0.10167832598090172,0.5156459659337997,0.28137193992733955,0.10756293497979642,0.10925409458577634,0.32394714653491974,0.10553485304117204,0.0860912248492241,0.3546902909874916,0.12427419014275075,0.2829314567148686,0.1633545655757189,0.11223207078874112,0.11903460882604124,0.35821877717971806,0.11251056455075742,0.11384665668010713,0.22998050674796106,0.14578848704695702,0.22092887610197068,0.10071831308305264,0.12188248112797738,0.12420923374593258,0.2813253901898861,0.12405379302799703,0.2083232916891575,0.46487810611724856,0.16749810576438906,0.26806456893682484,0.10851157195866108,0.13009082525968552,0.12688109613955023,0.2898755148053169,0.13753882348537447,0.2577830716967583,0.17829358130693437,0.16354098580777646,0.12527223341166974,0.08917633183300495,0.1320855036377907,0.12739758901298048,0.19218101352453232,0.14197779558598997,0.35319715887308123,0.06741776447743178,0.15761889964342118,0.04084996450692416,0.07334743961691857,0.13149371445178987,0.12683158926665783,0.14120552055537702,0.14144478701055052,0.3369572952389717,0.04757114611566067,0.16487951204180717,0.03264276450499892,0.07273645419627428,0.13116803728044035,0.127137703076005,0.089138925075531,0.14031972773373128,0.3319104708731175,0.039260345790535216,0.15436116233468056,0.03534103492274881,0.06885472107678653,0.12991811446845533,0.12614560425281526,0.06290892250835896,0.13668489530682565,0.13514871373772622,0.02999556250870228,0.12364344522356988,0.03050988279283047,0.05796121247112752,0.12565156146883966,0.1222495883703232,0.05130967944860459,0.1297759607434273,0.09033160619437695,0.03306763647124172,0.10747762061655522,0.03593307808041573,0.06231307480484247,0.12103274725377561,0.12066990472376347,0.05398421231657267,0.12235910296440125,0.07643184754997492,0.0395142118446529,0.09810982793569566,0.03995051253587008,0.06900277398526669,0.11493384651839735,0.11653186641633512,0.0593707200139761,0.1144467942416668,0.06047666352242232,0.04047167748212815,0.08352814782410861,0.028649495076388122,0.08122366424649954,0.11203573308885098,0.11272982507944108,0.05679134856909514,0.11286671832203866],\"_display_name\":[\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\"],\"_formatted_entropy\":[\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\"],\"_formatted_kl_unif\":[\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\"],\"checkpoint\":[\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\"],\"display_col\":[\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\"],\"exp_name\":[\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\"],\"exp_type\":[\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\"],\"gamma\":{\"__ndarray__\":\"AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/\",\"dtype\":\"float64\",\"shape\":[225]},\"index\":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224],\"label\":[\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\"],\"layer_num\":[0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8,8,9,9,9,9,9,9,9,9,9,10,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,12,13,13,13,13,13,13,13,13,13,14,14,14,14,14,14,14,14,14,15,15,15,15,15,15,15,15,15,16,16,16,16,16,16,16,16,16,17,17,17,17,17,17,17,17,17,18,18,18,18,18,18,18,18,18,19,19,19,19,19,19,19,19,19,20,20,20,20,20,20,20,20,20,21,21,21,21,21,21,21,21,21,22,22,22,22,22,22,22,22,22,23,23,23,23,23,23,23,23,23,24,24,24,24,24,24,24,24,24],\"layer_weight\":[0.016645729541778564,0.014840422198176384,0.034396544098854065,0.01395844854414463,0.04746822640299797,0.03494350239634514,0.03694916144013405,0.022849587723612785,0.03768207132816315,0.015939930453896523,0.009873905219137669,0.03424072265625,0.01112339273095131,0.03525629639625549,0.03475894778966904,0.03629613295197487,0.018913112580776215,0.03373712673783302,0.01635926589369774,0.00827826652675867,0.03251620754599571,0.01068835984915495,0.029375694692134857,0.034643154591321945,0.036049168556928635,0.01617020182311535,0.03344852849841118,0.015488582663238049,0.009606171399354935,0.03151877224445343,0.011094332672655582,0.02790132537484169,0.03466639667749405,0.035841021686792374,0.016600580886006355,0.0333741270005703,0.014735406264662743,0.012889089062809944,0.02952652797102928,0.011475945822894573,0.02373284101486206,0.03507283329963684,0.0355541966855526,0.01871928758919239,0.034128982573747635,0.014450948685407639,0.014354066923260689,0.03031102754175663,0.011259407736361027,0.026751581579446793,0.03502510115504265,0.03515740856528282,0.02029910683631897,0.03376557305455208,0.014387178234755993,0.013704154640436172,0.030553355813026428,0.010256863199174404,0.029555601999163628,0.03482186421751976,0.034876011312007904,0.02013048529624939,0.03306976705789566,0.014624624513089657,0.010685679502785206,0.032581914216279984,0.011421430855989456,0.02998463250696659,0.0345412977039814,0.034771230071783066,0.014868740923702717,0.0327116921544075,0.013790440745651722,0.008341295644640923,0.03133086860179901,0.009947897866368294,0.028805993497371674,0.03435106202960014,0.03449413180351257,0.013711939565837383,0.03247329592704773,0.015656867995858192,0.006904524751007557,0.030480647459626198,0.013347301632165909,0.03709457442164421,0.03393173590302467,0.03380795195698738,0.014484752900898457,0.03156648203730583,0.01597868837416172,0.01177357230335474,0.02811529114842415,0.030895736068487167,0.04156896099448204,0.03414982929825783,0.034013163298368454,0.018035979941487312,0.031626146286726,0.019321173429489136,0.04121406003832817,0.03137437254190445,0.08973799645900726,0.09179097414016724,0.03632569685578346,0.034777309745550156,0.03259719908237457,0.03345836326479912,0.024715043604373932,0.09509938210248947,0.033276595175266266,0.15119294822216034,0.09568648040294647,0.0382915697991848,0.03701581433415413,0.04659787937998772,0.036174967885017395,0.028462322428822517,0.17756851017475128,0.03765863925218582,0.1909799873828888,0.10421182960271835,0.03983812406659126,0.040464479476213455,0.11998042464256287,0.03908698260784149,0.03188563883304596,0.1313667744398117,0.04602747783064842,0.10478942841291428,0.060501690953969955,0.04156743362545967,0.044086892157793045,0.13267362117767334,0.041670579463243484,0.04216542840003967,0.0851779654622078,0.05399573594331741,0.08182550966739655,0.037303078919649124,0.045141659677028656,0.046003419905900955,0.10419458895921707,0.045945849269628525,0.07715677469968796,0.17217707633972168,0.062036335468292236,0.09928317368030548,0.0401894710958004,0.04818178713321686,0.04699299857020378,0.10736130177974701,0.05094030499458313,0.0954752117395401,0.06603465974330902,0.06057073548436165,0.046397123485803604,0.03302827104926109,0.04892055690288544,0.0471842922270298,0.07117815315723419,0.052584368735551834,0.13081376254558563,0.024969542399048805,0.05837737023830414,0.015129616484045982,0.027165718376636505,0.04870137572288513,0.04697466269135475,0.05229834094643593,0.05238695815205574,0.12479899823665619,0.017618943005800247,0.061066485941410065,0.01208991277962923,0.026939427480101585,0.048580754548311234,0.04708803817629814,0.03301441669464111,0.05197026953101158,0.12292980402708054,0.014540868811309338,0.0571708008646965,0.013089272193610668,0.02550174854695797,0.04811782017350197,0.04672059416770935,0.023299600929021835,0.05062403529882431,0.05005507916212082,0.011109467595815659,0.045793868601322174,0.01129995658993721,0.021467115730047226,0.0465376153588295,0.04527762532234192,0.01900358498096466,0.048065170645713806,0.03345615044236183,0.01224727276712656,0.03980652615427971,0.01330854743719101,0.0230789165943861,0.044826943427324295,0.04469255730509758,0.019994152709841728,0.04531818628311157,0.028308091685175896,0.014634893275797367,0.03633697330951691,0.014796486124396324,0.02555658295750618,0.04256809130311012,0.04315995052456856,0.021989155560731888,0.0423877015709877,0.02239876426756382,0.014989510178565979,0.03093635104596615,0.01061092410236597,0.030082838609814644,0.041494715958833694,0.041751787066459656,0.02103383280336857,0.04180248826742172],\"run\":[\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\"],\"scalar_set\":[\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\"],\"tag\":[\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\"],\"task\":[\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\"],\"weight_entropy\":[4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481],\"weight_exp_layer\":{\"__ndarray__\":\"AABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipA\",\"dtype\":\"float64\",\"shape\":[225]},\"weight_exp_layer_oneplus\":{\"__ndarray__\":\"SG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytA\",\"dtype\":\"float64\",\"shape\":[225]},\"weight_kl_unif\":{\"__ndarray__\":\"w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/\",\"dtype\":\"float64\",\"shape\":[225]}},\"selected\":{\"id\":\"3378\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"3379\",\"type\":\"UnionRenderers\"}},\"id\":\"3234\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"callback\":null,\"data\":{\"_bar_center\":[\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\"],\"_bar_height\":[0.04494346976280213,0.04006913993507624,0.09287066906690598,0.0376878110691905,0.12816421128809452,0.09434745647013187,0.09976273588836193,0.06169388685375452,0.1017415925860405,0.04303781222552061,0.02665954409167171,0.092449951171875,0.030033160373568537,0.09519200026988983,0.0938491590321064,0.09799955897033215,0.05106540396809578,0.09109024219214917,0.044170017912983896,0.022351319622248414,0.08779376037418843,0.028858571592718364,0.07931437566876412,0.09353651739656926,0.09733275510370731,0.04365954492241145,0.0903110269457102,0.041819173190742735,0.025936662778258325,0.08510068506002427,0.029954698216170073,0.07533357851207256,0.09359927102923393,0.09677075855433942,0.04482156839221716,0.0901101429015398,0.03978559691458941,0.03480054046958685,0.07972162552177907,0.03098505372181535,0.06407867074012757,0.09469664990901948,0.09599633105099202,0.05054207649081946,0.09214825294911862,0.039017561450600625,0.038755980692803865,0.08183977436274291,0.030400400888174774,0.07222927026450635,0.09456777311861515,0.09492500312626362,0.054807588458061225,0.09116704724729062,0.03884538123384118,0.03700121752917767,0.08249406069517136,0.027693530637770893,0.0798001253977418,0.09401903338730336,0.09416523054242135,0.054352310299873356,0.08928837105631829,0.039486486185342076,0.02885133465752006,0.08797116838395597,0.030837863311171533,0.0809585077688098,0.09326150380074978,0.09388232119381429,0.04014560049399734,0.08832156881690026,0.03723419001325965,0.022521498240530492,0.08459334522485734,0.026859324239194394,0.07777618244290352,0.09274786747992039,0.09313415586948395,0.037022236827760936,0.08767789900302887,0.042273543588817124,0.018642216827720406,0.08229774814099074,0.03603771440684796,0.10015535093843937,0.09161568693816663,0.09128147028386593,0.03910883283242583,0.08522950150072575,0.04314245861023665,0.031788645219057804,0.07591128610074521,0.08341848738491536,0.11223619468510151,0.09220453910529613,0.09183554090559483,0.048697145842015746,0.0853905949741602,0.05216716825962067,0.11127796210348607,0.08471080586314202,0.24229259043931964,0.24783563017845156,0.09807938151061535,0.09389873631298543,0.08801243752241135,0.09033758081495763,0.06673061773180962,0.2567683316767216,0.08984680697321892,0.40822096019983295,0.2583534970879555,0.10338723845779896,0.09994269870221616,0.12581427432596684,0.09767241328954697,0.0768482705578208,0.4794349774718285,0.10167832598090172,0.5156459659337997,0.28137193992733955,0.10756293497979642,0.10925409458577634,0.32394714653491974,0.10553485304117204,0.0860912248492241,0.3546902909874916,0.12427419014275075,0.2829314567148686,0.1633545655757189,0.11223207078874112,0.11903460882604124,0.35821877717971806,0.11251056455075742,0.11384665668010713,0.22998050674796106,0.14578848704695702,0.22092887610197068,0.10071831308305264,0.12188248112797738,0.12420923374593258,0.2813253901898861,0.12405379302799703,0.2083232916891575,0.46487810611724856,0.16749810576438906,0.26806456893682484,0.10851157195866108,0.13009082525968552,0.12688109613955023,0.2898755148053169,0.13753882348537447,0.2577830716967583,0.17829358130693437,0.16354098580777646,0.12527223341166974,0.08917633183300495,0.1320855036377907,0.12739758901298048,0.19218101352453232,0.14197779558598997,0.35319715887308123,0.06741776447743178,0.15761889964342118,0.04084996450692416,0.07334743961691857,0.13149371445178987,0.12683158926665783,0.14120552055537702,0.14144478701055052,0.3369572952389717,0.04757114611566067,0.16487951204180717,0.03264276450499892,0.07273645419627428,0.13116803728044035,0.127137703076005,0.089138925075531,0.14031972773373128,0.3319104708731175,0.039260345790535216,0.15436116233468056,0.03534103492274881,0.06885472107678653,0.12991811446845533,0.12614560425281526,0.06290892250835896,0.13668489530682565,0.13514871373772622,0.02999556250870228,0.12364344522356988,0.03050988279283047,0.05796121247112752,0.12565156146883966,0.1222495883703232,0.05130967944860459,0.1297759607434273,0.09033160619437695,0.03306763647124172,0.10747762061655522,0.03593307808041573,0.06231307480484247,0.12103274725377561,0.12066990472376347,0.05398421231657267,0.12235910296440125,0.07643184754997492,0.0395142118446529,0.09810982793569566,0.03995051253587008,0.06900277398526669,0.11493384651839735,0.11653186641633512,0.0593707200139761,0.1144467942416668,0.06047666352242232,0.04047167748212815,0.08352814782410861,0.028649495076388122,0.08122366424649954,0.11203573308885098,0.11272982507944108,0.05679134856909514,0.11286671832203866],\"_display_name\":[\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\"],\"_formatted_entropy\":[\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\",\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\"],\"_formatted_kl_unif\":[\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\",\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\"],\"checkpoint\":[\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\"],\"display_col\":[\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\"],\"exp_name\":[\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\"],\"exp_type\":[\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\"],\"gamma\":{\"__ndarray__\":\"AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/\",\"dtype\":\"float64\",\"shape\":[225]},\"index\":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224],\"label\":[\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\"],\"layer_num\":[0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8,8,9,9,9,9,9,9,9,9,9,10,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,12,13,13,13,13,13,13,13,13,13,14,14,14,14,14,14,14,14,14,15,15,15,15,15,15,15,15,15,16,16,16,16,16,16,16,16,16,17,17,17,17,17,17,17,17,17,18,18,18,18,18,18,18,18,18,19,19,19,19,19,19,19,19,19,20,20,20,20,20,20,20,20,20,21,21,21,21,21,21,21,21,21,22,22,22,22,22,22,22,22,22,23,23,23,23,23,23,23,23,23,24,24,24,24,24,24,24,24,24],\"layer_weight\":[0.016645729541778564,0.014840422198176384,0.034396544098854065,0.01395844854414463,0.04746822640299797,0.03494350239634514,0.03694916144013405,0.022849587723612785,0.03768207132816315,0.015939930453896523,0.009873905219137669,0.03424072265625,0.01112339273095131,0.03525629639625549,0.03475894778966904,0.03629613295197487,0.018913112580776215,0.03373712673783302,0.01635926589369774,0.00827826652675867,0.03251620754599571,0.01068835984915495,0.029375694692134857,0.034643154591321945,0.036049168556928635,0.01617020182311535,0.03344852849841118,0.015488582663238049,0.009606171399354935,0.03151877224445343,0.011094332672655582,0.02790132537484169,0.03466639667749405,0.035841021686792374,0.016600580886006355,0.0333741270005703,0.014735406264662743,0.012889089062809944,0.02952652797102928,0.011475945822894573,0.02373284101486206,0.03507283329963684,0.0355541966855526,0.01871928758919239,0.034128982573747635,0.014450948685407639,0.014354066923260689,0.03031102754175663,0.011259407736361027,0.026751581579446793,0.03502510115504265,0.03515740856528282,0.02029910683631897,0.03376557305455208,0.014387178234755993,0.013704154640436172,0.030553355813026428,0.010256863199174404,0.029555601999163628,0.03482186421751976,0.034876011312007904,0.02013048529624939,0.03306976705789566,0.014624624513089657,0.010685679502785206,0.032581914216279984,0.011421430855989456,0.02998463250696659,0.0345412977039814,0.034771230071783066,0.014868740923702717,0.0327116921544075,0.013790440745651722,0.008341295644640923,0.03133086860179901,0.009947897866368294,0.028805993497371674,0.03435106202960014,0.03449413180351257,0.013711939565837383,0.03247329592704773,0.015656867995858192,0.006904524751007557,0.030480647459626198,0.013347301632165909,0.03709457442164421,0.03393173590302467,0.03380795195698738,0.014484752900898457,0.03156648203730583,0.01597868837416172,0.01177357230335474,0.02811529114842415,0.030895736068487167,0.04156896099448204,0.03414982929825783,0.034013163298368454,0.018035979941487312,0.031626146286726,0.019321173429489136,0.04121406003832817,0.03137437254190445,0.08973799645900726,0.09179097414016724,0.03632569685578346,0.034777309745550156,0.03259719908237457,0.03345836326479912,0.024715043604373932,0.09509938210248947,0.033276595175266266,0.15119294822216034,0.09568648040294647,0.0382915697991848,0.03701581433415413,0.04659787937998772,0.036174967885017395,0.028462322428822517,0.17756851017475128,0.03765863925218582,0.1909799873828888,0.10421182960271835,0.03983812406659126,0.040464479476213455,0.11998042464256287,0.03908698260784149,0.03188563883304596,0.1313667744398117,0.04602747783064842,0.10478942841291428,0.060501690953969955,0.04156743362545967,0.044086892157793045,0.13267362117767334,0.041670579463243484,0.04216542840003967,0.0851779654622078,0.05399573594331741,0.08182550966739655,0.037303078919649124,0.045141659677028656,0.046003419905900955,0.10419458895921707,0.045945849269628525,0.07715677469968796,0.17217707633972168,0.062036335468292236,0.09928317368030548,0.0401894710958004,0.04818178713321686,0.04699299857020378,0.10736130177974701,0.05094030499458313,0.0954752117395401,0.06603465974330902,0.06057073548436165,0.046397123485803604,0.03302827104926109,0.04892055690288544,0.0471842922270298,0.07117815315723419,0.052584368735551834,0.13081376254558563,0.024969542399048805,0.05837737023830414,0.015129616484045982,0.027165718376636505,0.04870137572288513,0.04697466269135475,0.05229834094643593,0.05238695815205574,0.12479899823665619,0.017618943005800247,0.061066485941410065,0.01208991277962923,0.026939427480101585,0.048580754548311234,0.04708803817629814,0.03301441669464111,0.05197026953101158,0.12292980402708054,0.014540868811309338,0.0571708008646965,0.013089272193610668,0.02550174854695797,0.04811782017350197,0.04672059416770935,0.023299600929021835,0.05062403529882431,0.05005507916212082,0.011109467595815659,0.045793868601322174,0.01129995658993721,0.021467115730047226,0.0465376153588295,0.04527762532234192,0.01900358498096466,0.048065170645713806,0.03345615044236183,0.01224727276712656,0.03980652615427971,0.01330854743719101,0.0230789165943861,0.044826943427324295,0.04469255730509758,0.019994152709841728,0.04531818628311157,0.028308091685175896,0.014634893275797367,0.03633697330951691,0.014796486124396324,0.02555658295750618,0.04256809130311012,0.04315995052456856,0.021989155560731888,0.0423877015709877,0.02239876426756382,0.014989510178565979,0.03093635104596615,0.01061092410236597,0.030082838609814644,0.041494715958833694,0.041751787066459656,0.02103383280336857,0.04180248826742172],\"run\":[\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\"],\"scalar_set\":[\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\"],\"tag\":[\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\"],\"task\":[\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\"],\"weight_entropy\":[4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481,4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481],\"weight_exp_layer\":{\"__ndarray__\":\"AABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipAAABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipA\",\"dtype\":\"float64\",\"shape\":[225]},\"weight_exp_layer_oneplus\":{\"__ndarray__\":\"SG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytASG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytA\",\"dtype\":\"float64\",\"shape\":[225]},\"weight_kl_unif\":{\"__ndarray__\":\"w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/\",\"dtype\":\"float64\",\"shape\":[225]}},\"selected\":{\"id\":\"3374\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"3375\",\"type\":\"UnionRenderers\"}},\"id\":\"3221\",\"type\":\"ColumnDataSource\"},{\"attributes\":{},\"id\":\"3382\",\"type\":\"Selection\"}],\"root_ids\":[\"3199\"]},\"title\":\"Bokeh Application\",\"version\":\"1.0.4\"}};\n", - " var render_items = [{\"docid\":\"a0d84aec-43c1-44fb-af19-4abe86c671d6\",\"roots\":{\"3199\":\"19d4a817-f6fb-41ad-813a-b5134fd5cc22\"}}];\n", - " root.Bokeh.embed.embed_items_notebook(docs_json, render_items);\n", - "\n", - " }\n", - " if (root.Bokeh !== undefined) {\n", - " embed_document(root);\n", - " } else {\n", - " var attempts = 0;\n", - " var timer = setInterval(function(root) {\n", - " if (root.Bokeh !== undefined) {\n", - " embed_document(root);\n", - " clearInterval(timer);\n", - " }\n", - " attempts++;\n", - " if (attempts > 100) {\n", - " console.log(\"Bokeh: ERROR: Unable to run BokehJS code because BokehJS library is missing\");\n", - " clearInterval(timer);\n", - " }\n", - " }, 10, root)\n", - " }\n", - "})(window);" - ], - "application/vnd.bokehjs_exec.v0+json": "" - }, - "metadata": { - "application/vnd.bokehjs_exec.v0+json": { - "id": "3199" - } - }, - "output_type": "display_data" - } - ], - "source": [ - "# https://bokeh.pydata.org/en/latest/docs/reference/palettes.html\n", - "palette = bokeh.palettes.Category20c_20\n", - "\n", - "# MODEL_NAME = \"bert-base-uncased\"\n", - "MODEL_NAME = \"bert-large-uncased\"\n", - "EXPT_TYPES = [f\"{MODEL_NAME}-mix\"]\n", - "SCORE_EXPT_TYPE = f\"{MODEL_NAME}-mix\"\n", - "MAX_LAYER = 24 if '-large-' in MODEL_NAME else 12\n", - "WEIGHT_SCALE = 2.7 if '-large-' in MODEL_NAME else 2.1\n", - "# SCORE_SCALE = 1.5\n", - "# SCORE_SCALE = 2.2\n", - "SCORE_SCALE = WEIGHT_SCALE\n", - "WEIGHT_COLORS = (palette[0], palette[9]) # blue, green\n", - "SCORE_COLORS = (palette[12], palette[12]) # purples\n", - "NEG_COLORS = (palette[5], palette[4]) # oranges\n", - "# PLOT_WIDTH = 900\n", - "PLOT_WIDTH=450\n", - "# _PLOT_HEIGHT_FN=lambda num_cats: 80 + 100*num_cats\n", - "_PLOT_HEIGHT_FN=lambda num_cats: 750\n", - "\n", - "##\n", - "# Don't change below here\n", - "##\n", - "def _make_display_name(task, label):\n", - " if task.startswith(\"pos-\"):\n", - " return \"POS\"\n", - " elif task.startswith(\"coref-\"):\n", - " return \"Coref.\"\n", - " elif task.startswith(\"spr\"):\n", - " return \"SPR\"\n", - " elif task.startswith(\"rel-\"):\n", - " return \"Relations\"\n", - " elif task.startswith(\"dep-\"):\n", - " return \"Deps.\"\n", - " elif task.startswith(\"nonterminal-\"):\n", - " return \"Consts.\"\n", - " else:\n", - " return analysis.make_display_name(task, label) \n", - "\n", - "def _make_mask(df):\n", - " mask = df['exp_type'].map(lambda s: s in EXPT_TYPES)\n", - " mask &= df['task'] != 'constituent-ontonotes' # don't use this task\n", - " mask &= df['task'] != 'ner-tacred' # don't use this task\n", - " mask &= df['task'] != 'coref-gap-ontonotes' # don't use this task\n", - " mask &= df['task'] != 'rel-tacred' # don't use this task\n", - "# mask &= df['task'] != 'rel-semeval' # don't use this task\n", - " # Skip Winograd and SPR2 for this\n", - " mask &= df['task'] != 'dpr'\n", - "# mask &= df['task'] != 'spr1'\n", - " mask &= df['task'] != 'spr2'\n", - " return mask\n", - "\n", - "mask = _make_mask(scalar_df)\n", - "weight_df = scalar_df[mask].copy()\n", - "\n", - "##\n", - "# Make long-form DataFrame and add plotting values\n", - "skip_cols = set(scalar_columns.keys()).union(scalar_columns.values())\n", - "id_vars = [c for c in weight_df.columns if c not in skip_cols]\n", - "value_vars = scalar_columns.keys()\n", - "weight_df = pd.melt(weight_df, id_vars=id_vars, value_vars=value_vars, \n", - " var_name=\"layer_num\", value_name=\"layer_weight\")\n", - "weight_df['label'] = None\n", - "\n", - "##\n", - "# Append the scores DataFrame\n", - "mask = _make_mask(fdf)\n", - "mask &= fdf['layer_num'].notnull()\n", - "mask &= fdf['exp_type'] == SCORE_EXPT_TYPE\n", - "# mask &= fdf['layer_num'].astype(float) > 0\n", - "score_df = fdf[mask].copy()\n", - "# Erase labels, for now\n", - "score_df['label'] = None\n", - "\n", - "##\n", - "# Plotting code below this line\n", - "##\n", - "\n", - "# Row keys\n", - "sorted_tasks = sorted(weight_df['task'].unique(), key=task_sort_key)\n", - "cats = [_make_display_name(t, None) for t in sorted_tasks]\n", - "cats = list(reversed(cats))\n", - "PLOT_HEIGHT = _PLOT_HEIGHT_FN(len(cats))\n", - "\n", - "# Row names, matching row keys\n", - "score_df['_display_name'] = list(map(_make_display_name, score_df['task'], score_df['label']))\n", - "weight_df['_display_name'] = list(map(_make_display_name, weight_df['task'], weight_df['label']))\n", - "\n", - "# Bar heights for weights\n", - "weight_df['_bar_height'] = weight_df['layer_weight'] * WEIGHT_SCALE\n", - "weight_df['_bar_center'] = weight_df['_display_name']\n", - "weight_df['_formatted_entropy'] = weight_df['weight_entropy'].map(lambda h: \"H(s) = {:.02f} bits\".format(h))\n", - "# weight_df['_formatted_kl_unif'] = weight_df['weight_kl_unif'].map(lambda h: \"KL(s||uniform) = {:.02f} bits\".format(h))\n", - "weight_df['_formatted_kl_unif'] = weight_df['weight_kl_unif'].map(lambda h: \"K(s) = {:.02f}\".format(h))\n", - "# weight_df['_formatted_exp_layer'] = weight_df['weight_exp_layer_oneplus'].map(lambda l: \"E[k] = {:.02f}\".format(l))\n", - "\n", - "# Bar heights for scores (cumulative)\n", - "# score_df['_bar_height'] = score_df['real_headroom_frac'] * SCORE_SCALE\n", - "score_df['_bar_height'] = score_df['headroom_frac'] * SCORE_SCALE\n", - "score_df['_bar_height'] = score_df['_bar_height'].map(lambda h: min(h, 1.0))\n", - "# Add offset so bars start at baseline\n", - "score_df['_bar_center'] = [(l, h/2-0.5) for l, h in zip(score_df['_display_name'], score_df['_bar_height'])]\n", - "# score_df['_bar_center'] = score_df[\"_display_name\"]\n", - "\n", - "score_df['_fill_color'] = [SCORE_COLORS[0] if h > 0 else NEG_COLORS[0] for h in score_df['_bar_height']]\n", - "score_df['_line_color'] = [SCORE_COLORS[1] if h > 0 else NEG_COLORS[1] for h in score_df['_bar_height']]\n", - "score_df['_bar_height'] = score_df['_bar_height'].map(np.abs)\n", - "\n", - "# score_df['_formatted_exp_layer'] = score_df['exp_layer'].map(lambda l: \"E[layer] = {:.02f}\".format(l))\n", - "score_df['_formatted_exp_layer'] = score_df['exp_layer'].map(lambda l: \"{:.02f}\".format(l))\n", - "score_df['_formatted_kl_unif'] = score_df['kl_unif'].map(lambda h: \"K(Δ) = {:.02f}\".format(h))\n", - "\n", - "hover_0 = bokeh.models.HoverTool(\n", - " tooltips=[\n", - " (\"task\", \"@_display_name\"),\n", - " (\"experiment\", \"@exp_type\"),\n", - " (\"layer\", \"@layer_num\"),\n", - " (\"weight\", \"@layer_weight{0.0%}\"),\n", - " ],\n", - " renderers=[],\n", - ")\n", - "hover_2 = bokeh.models.HoverTool(\n", - " tooltips=[\n", - " (\"task\", \"@_display_name\"),\n", - " (\"experiment\", \"@exp_type\"),\n", - " (\"layer\", \"@layer_num\"),\n", - " (\"score\", \"@score{0.0%} (Δ @delta_score{0.0%})\"),\n", - " (\"headroom fraction\", \"@headroom_frac{0.0%}\"),\n", - " ],\n", - " renderers=[],\n", - ")\n", - "\n", - "x_range = (-0.5, MAX_LAYER+0.5)\n", - "p = bp.figure(y_range=bokeh.models.FactorRange(*cats, factor_padding=0.10), x_range=x_range,\n", - " plot_width=PLOT_WIDTH, plot_height=PLOT_HEIGHT, tools=[hover_0, hover_2, 'save'])\n", - "\n", - "##\n", - "# Add background bars\n", - "bgbar_color = \"#f2f2f2\"\n", - "p.hbar(y='_display_name', left=x_range[0], right=x_range[1], \n", - " height=1.0, \n", - " fill_color=bgbar_color, fill_alpha=0.40, \n", - "# line_color=\"#e6e6e6\", \n", - "# line_alpha=0.80,\n", - "# line_color=\"Gray\",\n", - " line_alpha=0.0,\n", - "# line_width=0.5,\n", - " source=weight_df, \n", - " level='image')\n", - "p.hbar(y='_display_name', left=x_range[0], right=x_range[1], \n", - " height=1.0, \n", - " fill_color=\"White\", fill_alpha=0.0,\n", - " line_color=\"#e6e6e6\",\n", - " line_alpha=1.0,\n", - " line_width=0.5,\n", - " source=weight_df, \n", - " level='underlay')\n", - "\n", - "def _plot_bars(sdf, x_dodge=0, y_dodge=0, **kw):\n", - " y = bokeh.transform.dodge('_bar_center', y_dodge, range=p.y_range)\n", - " x = 'layer_num'\n", - " bars = p.rect(x=x, y=y, width=0.9, height=\"_bar_height\", source=sdf, **kw)\n", - " shadow_bars = p.rect(x=x, y=y, width=0.9, height=0.5, source=sdf, alpha=0.0)\n", - " return bars, shadow_bars\n", - "\n", - "##\n", - "# Plot weights and delta scores\n", - "_WEIGHT_BAR_PARAMS = dict(fill_color=WEIGHT_COLORS[0], line_color=WEIGHT_COLORS[0],\n", - "# line_width=1.5, fill_alpha=0.1,\n", - " )\n", - "_SCORE_BAR_PARAMS = dict(fill_color='_fill_color', line_color='_line_color', \n", - " line_width=1.5, fill_alpha=0.1,\n", - " )\n", - "b0, s0 = _plot_bars(weight_df[weight_df.exp_type == EXPT_TYPES[0]], y_dodge=0, \n", - " hover_fill_color=\"firebrick\", hover_fill_alpha=1.0,\n", - " **_WEIGHT_BAR_PARAMS)\n", - "b2, s2 = _plot_bars(score_df[score_df['layer_num'].map(int) > 0], y_dodge=0, \n", - " hover_fill_color=\"firebrick\", hover_fill_alpha=0.7, **_SCORE_BAR_PARAMS)\n", - "hover_0.renderers.extend([b0, s0])\n", - "hover_2.renderers.extend([b2, s2])\n", - "\n", - "p.xaxis.ticker = bokeh.models.FixedTicker(ticks=np.arange(0, MAX_LAYER+1))\n", - "p.xgrid.ticker = p.xaxis[0].ticker\n", - " \n", - "_FONT_SIZE = \"13pt\"\n", - "p.yaxis.major_label_text_font_size = _FONT_SIZE\n", - "p.xaxis.major_label_text_font_size = _FONT_SIZE\n", - "# p.xaxis.axis_label = \"Encoder Layer\"\n", - "# p.xaxis.axis_label_text_font_size = _FONT_SIZE\n", - "\n", - "# p.yaxis.major_label_orientation = 60 * np.pi / 180\n", - "p.yaxis.major_label_orientation = \"vertical\"\n", - "if PLOT_WIDTH < 600 and MAX_LAYER > 12:\n", - " p.xaxis.ticker = bokeh.models.FixedTicker(ticks=np.arange(0, MAX_LAYER+1, 2))\n", - "\n", - "# p.toolbar.autohide = True\n", - "\n", - "# Add labels with entropy\n", - "# _label_y = [28, 10]\n", - "label_kw = [\n", - " dict(x=x_range[1], y_offset=18, x_offset=-10, text_baseline=\"bottom\", text_align=\"right\"),\n", - " dict(x=x_range[1]*0.20, y_offset=18, x_offset=0, text_baseline=\"bottom\", text_align=\"left\"),\n", - "]\n", - "LABEL_COLOR = \"#404040\"\n", - "score_labels = bokeh.models.annotations.LabelSet(\n", - " y=\"_display_name\", text=\"_formatted_kl_unif\",\n", - " text_color=LABEL_COLOR, text_font_size=\"12pt\",\n", - " source=bokeh.models.ColumnDataSource(weight_df[weight_df['layer_num'] == 0]), **label_kw[0])\n", - "p.add_layout(score_labels)\n", - "score_labels = bokeh.models.annotations.LabelSet(\n", - " y=\"_display_name\", text=\"_formatted_kl_unif\",\n", - " text_color=LABEL_COLOR, text_font_size=\"12pt\",\n", - " source=bokeh.models.ColumnDataSource(score_df[score_df['layer_num'].map(int) == 0]), **label_kw[1])\n", - "p.add_layout(score_labels)\n", - "# # Add labels with expected layer\n", - "# score_labels = bokeh.models.annotations.LabelSet(\n", - "# y=\"_display_name\", \n", - "# # x=\"weight_exp_layer\",\n", - "# x=x_range[1] // 6, \n", - "# text=\"_formatted_exp_layer\",\n", - "# text_align=\"left\", text_baseline=\"bottom\", y_offset=25, x_offset=0,\n", - "# text_color=\"#595959\", text_font_size=\"11pt\",\n", - "# source=bokeh.models.ColumnDataSource(weight_df[weight_df['layer_num'] == 0]))\n", - "# p.add_layout(score_labels)\n", - "\n", - "# p.xgrid.visible = False\n", - "p.min_border_left = 0\n", - "p.min_border_right = 0\n", - "p.min_border_top = 0\n", - "p.min_border_bottom = 0\n", - "p.toolbar_location = None\n", - "\n", - "bp.show(p)" - ] - }, - { - "cell_type": "code", - "execution_count": 32, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Plot y range: weights:0.37, scores:0.37\n" - ] - } - ], - "source": [ - "print(f\"Plot y range: weights:{1/WEIGHT_SCALE:.2f}, scores:{1/SCORE_SCALE:.2f}\")" - ] - }, - { - "cell_type": "code", - "execution_count": 33, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Copying file:///tmp/bert-large-uncased.weights_and_scores.20190603.211908.html [Content-Type=text/html]...\n", - "/ [1 files][730.9 KiB/730.9 KiB] \n", - "Operation completed over 1 objects/730.9 KiB. \n", - "Updated ACL on gs://edge-probing/iftenney/plots/bert-large-uncased.weights_and_scores.20190603.211908.html\n", - "Public URL: https://storage.googleapis.com/edge-probing/iftenney/plots/bert-large-uncased.weights_and_scores.20190603.211908.html\n" - ] - }, - { - "data": { - "text/plain": [ - "'https://storage.googleapis.com/edge-probing/iftenney/plots/bert-large-uncased.weights_and_scores.20190603.211908.html'" - ] - }, - "execution_count": 33, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "_save_figure_to_bucket(p, name=f\"{MODEL_NAME}.weights_and_scores\" + (\".running_max\" if USE_RUNNING_MAX else \"\"),\n", - " title=f\"{MODEL_NAME} mixing weights and differential scores\" + (\" (running_max)\" if USE_RUNNING_MAX else \"\"))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Make aggregate plot" - ] - }, - { - "cell_type": "code", - "execution_count": 34, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": [ - "(function(root) {\n", - " function embed_document(root) {\n", - " \n", - " var docs_json = {\"d00e8a36-a6fd-4ba9-88b3-0b2d91d79ffa\":{\"roots\":{\"references\":[{\"attributes\":{\"children\":[{\"id\":\"3752\",\"subtype\":\"Figure\",\"type\":\"Plot\"},{\"id\":\"3708\",\"subtype\":\"Figure\",\"type\":\"Plot\"}]},\"id\":\"3786\",\"type\":\"Row\"},{\"attributes\":{},\"id\":\"3768\",\"type\":\"PanTool\"},{\"attributes\":{},\"id\":\"3924\",\"type\":\"Selection\"},{\"attributes\":{\"plot\":{\"id\":\"3752\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"source\":{\"id\":\"3783\",\"type\":\"ColumnDataSource\"},\"text\":{\"field\":\"_formatted_score\"},\"text_align\":\"center\",\"text_baseline\":\"middle\",\"x\":{\"field\":\"_formatted_layer_num\"},\"y\":{\"field\":\"_display_name\"}},\"id\":\"3784\",\"type\":\"LabelSet\"},{\"attributes\":{},\"id\":\"3769\",\"type\":\"WheelZoomTool\"},{\"attributes\":{\"range\":{\"id\":\"3706\",\"type\":\"FactorRange\"}},\"id\":\"3730\",\"type\":\"Dodge\"},{\"attributes\":{},\"id\":\"3909\",\"type\":\"CategoricalTickFormatter\"},{\"attributes\":{\"overlay\":{\"id\":\"3776\",\"type\":\"BoxAnnotation\"}},\"id\":\"3770\",\"type\":\"BoxZoomTool\"},{\"attributes\":{},\"id\":\"3771\",\"type\":\"SaveTool\"},{\"attributes\":{\"plot\":{\"id\":\"3708\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"source\":{\"id\":\"3747\",\"type\":\"ColumnDataSource\"},\"text\":{\"field\":\"_formatted_exp_layer\"},\"text_align\":\"right\",\"text_baseline\":\"middle\",\"text_color\":{\"value\":\"Black\"},\"text_font_size\":{\"value\":\"11pt\"},\"text_font_style\":\"bold\",\"x\":{\"field\":\"exp_layer\"},\"x_offset\":{\"value\":-6},\"y\":{\"field\":\"_display_name\",\"transform\":{\"id\":\"3740\",\"type\":\"Dodge\"}}},\"id\":\"3748\",\"type\":\"LabelSet\"},{\"attributes\":{},\"id\":\"3926\",\"type\":\"Selection\"},{\"attributes\":{},\"id\":\"3911\",\"type\":\"CategoricalTickFormatter\"},{\"attributes\":{},\"id\":\"3772\",\"type\":\"ResetTool\"},{\"attributes\":{\"callback\":null,\"data\":{\"_bar_center\":[[\"Coref.\",-0.33901404143352976],[\"Deps.\",-0.15535020398162452],[\"Entities\",0.0],[\"Consts.\",0.0],[\"POS\",0.0],[\"Relations\",-0.2810097744404242],[\"SPR\",-0.4021549339653747],[\"SRL\",-0.4402286837439977]],\"_bar_height\":{\"__ndarray__\":\"7T+UGTCb1D8lNZ4Evg7mPwAAAAAAAPA/AAAAAAAA8D8AAAAAAADwP3MFdijfB9w/wZSxzl8MyT8B5x2RWJq+Pw==\",\"dtype\":\"float64\",\"shape\":[8]},\"_display_name\":[\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\"],\"_fill_color\":[\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\"],\"_formatted_exp_layer\":[\"9.47\",\"5.69\",\"4.64\",\"3.79\",\"3.39\",\"9.40\",\"9.93\",\"6.54\"],\"_formatted_kl_unif\":[\"K(\\u0394) = 0.60\",\"K(\\u0394) = 1.15\",\"K(\\u0394) = 1.61\",\"K(\\u0394) = 1.57\",\"K(\\u0394) = 1.60\",\"K(\\u0394) = 0.50\",\"K(\\u0394) = 0.33\",\"K(\\u0394) = 1.31\"],\"_line_color\":[\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\"],\"accuracy\":{\"__ndarray__\":\"oB9HXNx57T8FFsSg89rvP//ZFX1Qx+8/aymEJd6V7z855byqzOPvPzcnkK3ZG+8/E01GLxS46z8VueqbtJ7vPw==\",\"dtype\":\"float64\",\"shape\":[8]},\"accuracy_errn95\":{\"__ndarray__\":\"I3yTc4araj+oo9ohfcQeP9htYP5dHzE/32/GaV4AFT8FDJMzuiEAPxKOJrH1XmI/GWL4AeGucz/PokNxgzciPw==\",\"dtype\":\"float64\",\"shape\":[8]},\"contextual_headroom\":[0.11639055893469108,0.09997559540642187,0.05733773727377656,0.1369172609382292,0.08318042260149905,0.23439707290638978,0.06260312292920267,0.10353468382410691],\"delta_score\":[0.013879441257917402,0.02552338412121402,0.02747614170542223,0.05941261708359613,0.03147784041096369,0.038022716937981205,0.0045373382940604445,0.004584003207641407],\"display_col\":[\"bert-large-uncased-mix-01 (base)\",\"bert-large-uncased-mix-01 (base)\",\"bert-large-uncased-mix-01 (base)\",\"bert-large-uncased-mix-01 (base)\",\"bert-large-uncased-mix-01 (base)\",\"bert-large-uncased-mix-01 (base)\",\"bert-large-uncased-mix-01 (base)\",\"bert-large-uncased-mix-01 (base)\"],\"display_row\":[\"coref-ontonotes-conll-1\",\"dep-labeling-ewt-_micro_avg_\",\"ner-ontonotes-_micro_avg_\",\"nonterminal-ontonotes-_micro_avg_\",\"pos-ontonotes-_micro_avg_\",\"rel-semeval-_clean_micro_\",\"spr1-_micro_avg_\",\"srl-conll2012-_clean_micro_\"],\"exp_layer\":[9.471179711705389,5.691932390197615,4.644666882875676,3.792980575634427,3.386439579545165,9.40046847774628,9.928992732451892,6.536649198760027],\"exp_name\":[\"bert-large-uncased-mix-01-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-01-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-01-edges-ner-ontonotes\",\"bert-large-uncased-mix-01-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-01-edges-pos-ontonotes\",\"bert-large-uncased-mix-01-edges-rel-semeval\",\"bert-large-uncased-mix-01-edges-spr1\",\"bert-large-uncased-mix-01-edges-srl-conll2012\"],\"exp_type\":[\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\"],\"f1_errn95\":{\"__ndarray__\":\"YbyXW15qhD+18UdmkO9vPzVmkoBF6Gs/XoZcAwvlWT/4KZkISH9QP4phtdNd+58/7W0xEZqbhT80oUgvMLZlPw==\",\"dtype\":\"float64\",\"shape\":[8]},\"f1_score\":{\"__ndarray__\":\"p0NJbJox6j/7roIqkTjsPw1xQeX63u0/iwDrqaRw6T84pOPQz1TtP0QeuIp2puQ/Ia/yfEj/6D8OkvtZLSvqPw==\",\"dtype\":\"float64\",\"shape\":[8]},\"fn_count\":{\"__ndarray__\":\"AAAAAACEkUAAAAAAAIquQAAAAAAAtJhAAAAAAOCw7kAAAAAAwAraQAAAAAAAUHtAAAAAAAAslUAAAAAAAFnSQA==\",\"dtype\":\"float64\",\"shape\":[8]},\"fp_count\":{\"__ndarray__\":\"AAAAAADgjUAAAAAAAKSbQAAAAAAAHJFAAAAAAGC64UAAAAAAgMHUQAAAAAAAYGFAAAAAAAAgk0AAAAAAAHLBQA==\",\"dtype\":\"float64\",\"shape\":[8]},\"headroom_frac\":[0.11924885819738537,0.2552961451987966,0.4791982211336487,0.43393080373117005,0.3784284742308631,0.16221498189598205,0.07247782669231503,0.04427504907852022],\"index\":[14,52,128,166,204,242,318,394],\"kl_unif\":{\"__ndarray__\":\"smln+9gk4z9Td0vmwGfyPyr7WHwku/k/1wcJs1Mx+T88bGlG7ob5PyG2W9ubCeA/Zn7/NR5c1T/dCjZNtOn0Pw==\",\"dtype\":\"float64\",\"shape\":[8]},\"label\":[\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\"],\"layer_num\":[\"01\",\"01\",\"01\",\"01\",\"01\",\"01\",\"01\",\"01\"],\"lex_score\":[0.804675649147854,0.8563817514420556,0.905993125093409,0.7355877588962386,0.8851251582672498,0.6072974644403215,0.7766251728907331,0.8131866690279881],\"max_layer_score\":[0.9210662080825451,0.9563573468484775,0.9633308623671856,0.8725050198344678,0.9683055808687488,0.8416945373467113,0.8392282958199357,0.916721352852095],\"num_epochs\":{\"__ndarray__\":\"AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fw==\",\"dtype\":\"float64\",\"shape\":[8]},\"num_steps\":{\"__ndarray__\":\"AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fw==\",\"dtype\":\"float64\",\"shape\":[8]},\"precision\":{\"__ndarray__\":\"UK7HUKyT6j9MNT3+GontP4lRXhaCPO4/MkW2mdXq6j+sfXgoOJztP5mFSpmFSuk/gzXqTzdH6T/sAICNTvvrPw==\",\"dtype\":\"float64\",\"shape\":[8]},\"precision_errn95\":{\"__ndarray__\":\"24dVEQ0NhD/uEi3FzT5sP/vOCt+z/mk/1b3EmfyMWD9mnKfLuKVPP0l5OzWrup8/D8TlLKZrhT8yQkh3CvNjPw==\",\"dtype\":\"float64\",\"shape\":[8]},\"pred_pos_count\":{\"__ndarray__\":\"AAAAAAAJtkAAAAAAgG7WQAAAAAAAZ9NAAAAAAEjnC0EAAAAA4F4RQQAAAAAAuIRAAAAAAADDtkAAAAAAoF3xQA==\",\"dtype\":\"float64\",\"shape\":[8]},\"prev_layer_score\":[0.8046756386756897,0.8563817739486694,0.9059931039810181,0.7355877757072449,0.8851251602172852,0.6072974801063538,0.7766251564025879,0.8131866455078125],\"prev_score_max\":{\"__ndarray__\":\"AAAAIOe/6T8AAADAemfrPwAAAEDl/ew/AAAAYO+J5z8AAAAA8lLsPwAAACD7buM/AAAAAB3a6D8AAAAAoAXqPw==\",\"dtype\":\"float64\",\"shape\":[8]},\"real_delta_score\":[0.013879441257917402,0.02552338412121402,0.02747614170542223,0.05941261708359613,0.03147784041096369,0.038022716937981205,0.0045373382940604445,0.004584003207641407],\"real_headroom_frac\":[0.11924885819738537,0.2552961451987966,0.4791982211336487,0.43393080373117005,0.3784284742308631,0.16221498189598205,0.07247782669231503,0.04427504907852022],\"recall\":{\"__ndarray__\":\"II//AlLS6T/oI73MtQTrP+Qmdmevg+0/oDmcEM4d6D86u6yrvA7tP614+1DQcuE/uuMiju646D+7h481iJPoPw==\",\"dtype\":\"float64\",\"shape\":[8]},\"recall_errn95\":{\"__ndarray__\":\"DsFbVSTLhD+ETeuhJ15yPzmuac6XH24/MFUELPNkWz9hBGI5CDtRP/jocTSNHqA/W0bajGbMhT/4UfsmxNBnPw==\",\"dtype\":\"float64\",\"shape\":[8]},\"run\":[\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-01-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-01-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-01-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-01-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-01-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-01-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-01-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-01-edges-srl-conll2012/run\"],\"score\":{\"__ndarray__\":\"p0NJbJox6j/7roIqkTjsPw1xQeX63u0/iwDrqaRw6T84pOPQz1TtP0QeuIp2puQ/Ia/yfEj/6D8OkvtZLSvqPw==\",\"dtype\":\"float64\",\"shape\":[8]},\"score_errn95\":{\"__ndarray__\":\"YbyXW15qhD+18UdmkO9vPzVmkoBF6Gs/XoZcAwvlWT/4KZkISH9QP4phtdNd+58/7W0xEZqbhT80oUgvMLZlPw==\",\"dtype\":\"float64\",\"shape\":[8]},\"seed\":[\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\"],\"split\":[\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\"],\"stratifier\":[\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\"],\"stratum_key\":{\"__ndarray__\":\"AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fw==\",\"dtype\":\"float64\",\"shape\":[8]},\"tag\":[\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\"],\"task\":[\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\"],\"tn_count\":{\"__ndarray__\":\"AAAAAMAc00AAAAAATb8yQQAAAAB0SxZBAAAAgP0VXEEAAACgMfVpQQAAAACAH9NAAAAAAACgx0AAAAAA6R5BQQ==\",\"dtype\":\"float64\",\"shape\":[8]},\"total_count\":{\"__ndarray__\":\"AAAAAEC32UAAAAAATCgzQQAAAACYmhdBAAAAgJkyXUEAAAAALo1qQQAAAACAMtRAAAAAAIDT0kAAAAAAiM5BQQ==\",\"dtype\":\"float64\",\"shape\":[8]},\"tp_count\":{\"__ndarray__\":\"AAAAAABNskAAAAAAQLTUQAAAAABAVdJAAAAAALB4B0EAAAAAyBIQQQAAAAAAYIBAAAAAAAD7sUAAAAAAwF7uQA==\",\"dtype\":\"float64\",\"shape\":[8]},\"true_pos_count\":{\"__ndarray__\":\"AAAAAACutkAAAAAAgIXYQAAAAACA4NNAAAAAAOgkD0EAAAAAdLMRQQAAAAAACI5AAAAAAABGt0AAAAAAoMXzQA==\",\"dtype\":\"float64\",\"shape\":[8]}},\"selected\":{\"id\":\"3926\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"3927\",\"type\":\"UnionRenderers\"}},\"id\":\"3747\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"callback\":null,\"start\":0},\"id\":\"3710\",\"type\":\"DataRange1d\"},{\"attributes\":{\"align\":\"center\",\"plot\":null,\"text\":\"Expected layer & center-of-gravity\"},\"id\":\"3707\",\"type\":\"Title\"},{\"attributes\":{},\"id\":\"3773\",\"type\":\"HelpTool\"},{\"attributes\":{\"callback\":null,\"data\":{\"_bar_center\":[[\"Coref.\",0.0],[\"Coref.\",-0.5175054552404181],[\"Deps.\",0.0],[\"Deps.\",-0.4970990208708064],[\"Entities\",0.0],[\"Entities\",-0.5345937972945325],[\"Consts.\",0.0],[\"Consts.\",-0.49044918351332795],[\"POS\",0.0],[\"POS\",-0.501252354593772],[\"Relations\",0.0],[\"Relations\",-0.4678961458829124],[\"SPR\",0.0],[\"SPR\",-0.5436214386873615],[\"SRL\",0.0],[\"SRL\",-0.525178457570553]],\"_bar_height\":{\"__ndarray__\":\"AAAAAAAA8D95aAk38+yhPwAAAAAAAPA/33uPT8vDdz8AAAAAAADwP1iHDDhHtrE/AAAAAAAA8D8szq7jYI+TPwAAAAAAAPA/NN58gcGEZD8AAAAAAADwPw9TBJfqb7A/AAAAAAAA8D/IJCKZjFW2PwAAAAAAAPA/niZRr2HIqT8=\",\"dtype\":\"float64\",\"shape\":[16]},\"_display_name\":[\"Coref.\",\"Coref.\",\"Deps.\",\"Deps.\",\"Entities\",\"Entities\",\"Consts.\",\"Consts.\",\"POS\",\"POS\",\"Relations\",\"Relations\",\"SPR\",\"SPR\",\"SRL\",\"SRL\"],\"_fill_color\":[\"#756bb1\",\"#fd8d3c\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#fd8d3c\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#fd8d3c\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#fd8d3c\",\"#756bb1\",\"#fd8d3c\"],\"_formatted_exp_layer\":[\"9.47\",\"9.47\",\"5.69\",\"5.69\",\"4.64\",\"4.64\",\"3.79\",\"3.79\",\"3.39\",\"3.39\",\"9.40\",\"9.40\",\"9.93\",\"9.93\",\"6.54\",\"6.54\"],\"_formatted_kl_unif\":[\"K(\\u0394) = 0.60\",\"K(\\u0394) = 0.60\",\"K(\\u0394) = 1.15\",\"K(\\u0394) = 1.15\",\"K(\\u0394) = 1.61\",\"K(\\u0394) = 1.61\",\"K(\\u0394) = 1.57\",\"K(\\u0394) = 1.57\",\"K(\\u0394) = 1.60\",\"K(\\u0394) = 1.60\",\"K(\\u0394) = 0.50\",\"K(\\u0394) = 0.50\",\"K(\\u0394) = 0.33\",\"K(\\u0394) = 0.33\",\"K(\\u0394) = 1.31\",\"K(\\u0394) = 1.31\"],\"_formatted_layer_num\":[\"\\u2113=0\",\"\\u2113=24\",\"\\u2113=0\",\"\\u2113=24\",\"\\u2113=0\",\"\\u2113=24\",\"\\u2113=0\",\"\\u2113=24\",\"\\u2113=0\",\"\\u2113=24\",\"\\u2113=0\",\"\\u2113=24\",\"\\u2113=0\",\"\\u2113=24\",\"\\u2113=0\",\"\\u2113=24\"],\"_formatted_score\":[\"80.5\",\"91.9\",\"85.6\",\"95.5\",\"90.6\",\"96.1\",\"73.6\",\"87.0\",\"88.5\",\"96.7\",\"60.7\",\"84.2\",\"77.7\",\"83.7\",\"81.3\",\"91.4\"],\"_line_color\":[\"#756bb1\",\"#e6550d\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#e6550d\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#e6550d\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#e6550d\",\"#756bb1\",\"#e6550d\"],\"accuracy\":{\"__ndarray__\":\"6gAKtwRX7T99yKU/0dzuP40akvZS0+8/GTWrvXTx7z+cOLk2DrDvP4Y4nqQE3+8/kICAocl87z/echWFWLnvP0ufXHlz2e8/pWmnb7r07z+tBwIWewTvP8cvPnCCj+8/CmbSQvS16z9pIfraPcHsP1DE6tIInO8/A4W/pXLQ7z8=\",\"dtype\":\"float64\",\"shape\":[16]},\"accuracy_errn95\":{\"__ndarray__\":\"/dwmrP1Qaz+tEEg66VFiP6h1bSSr4iA/HxqIQtZNEz+ORnvCF040PxAG6czaKCo/jRely61QFz/zKO0ZRywRPxlWlJ9K2QI/xt8Swi9r9D6vvsWos0JjP+UDb2Vt/Fk/wnJ+hQGzcz9gU1ahW3RxP20oUmNQdiI/zrZUto2MGT8=\",\"dtype\":\"float64\",\"shape\":[16]},\"contextual_headroom\":[0.11639055893469108,0.11639055893469108,0.09997559540642187,0.09997559540642187,0.05733773727377656,0.05733773727377656,0.1369172609382292,0.1369172609382292,0.08318042260149905,0.08318042260149905,0.23439707290638978,0.23439707290638978,0.06260312292920267,0.06260312292920267,0.10353468382410691,0.10353468382410691],\"delta_score\":[0.804675649147854,-0.0015092368295099856,0.8563817514420556,0.0002148349005205441,0.905993125093409,-0.0014692815263527281,0.7355877588962386,0.0009686456541324606,0.8851251582672498,-7.716398841250971e-05,0.6072974644403215,0.005574110691895617,0.7766251728907331,-0.0020228431766619037,0.8131866690279881,-0.0019309952916636286],\"display_col\":[\"bert-large-uncased-mix-00 (base)\",\"bert-large-uncased-mix-24 (base)\",\"bert-large-uncased-mix-00 (base)\",\"bert-large-uncased-mix-24 (base)\",\"bert-large-uncased-mix-00 (base)\",\"bert-large-uncased-mix-24 (base)\",\"bert-large-uncased-mix-00 (base)\",\"bert-large-uncased-mix-24 (base)\",\"bert-large-uncased-mix-00 (base)\",\"bert-large-uncased-mix-24 (base)\",\"bert-large-uncased-mix-00 (base)\",\"bert-large-uncased-mix-24 (base)\",\"bert-large-uncased-mix-00 (base)\",\"bert-large-uncased-mix-24 (base)\",\"bert-large-uncased-mix-00 (base)\",\"bert-large-uncased-mix-24 (base)\"],\"display_row\":[\"coref-ontonotes-conll-1\",\"coref-ontonotes-conll-1\",\"dep-labeling-ewt-_micro_avg_\",\"dep-labeling-ewt-_micro_avg_\",\"ner-ontonotes-_micro_avg_\",\"ner-ontonotes-_micro_avg_\",\"nonterminal-ontonotes-_micro_avg_\",\"nonterminal-ontonotes-_micro_avg_\",\"pos-ontonotes-_micro_avg_\",\"pos-ontonotes-_micro_avg_\",\"rel-semeval-_clean_micro_\",\"rel-semeval-_clean_micro_\",\"spr1-_micro_avg_\",\"spr1-_micro_avg_\",\"srl-conll2012-_clean_micro_\",\"srl-conll2012-_clean_micro_\"],\"exp_layer\":[9.471179711705389,9.471179711705389,5.691932390197615,5.691932390197615,4.644666882875676,4.644666882875676,3.792980575634427,3.792980575634427,3.386439579545165,3.386439579545165,9.40046847774628,9.40046847774628,9.928992732451892,9.928992732451892,6.536649198760027,6.536649198760027],\"exp_name\":[\"bert-large-uncased-mix-00-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-24-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-00-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-24-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-00-edges-ner-ontonotes\",\"bert-large-uncased-mix-24-edges-ner-ontonotes\",\"bert-large-uncased-mix-00-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-24-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-00-edges-pos-ontonotes\",\"bert-large-uncased-mix-24-edges-pos-ontonotes\",\"bert-large-uncased-mix-00-edges-rel-semeval\",\"bert-large-uncased-mix-24-edges-rel-semeval\",\"bert-large-uncased-mix-00-edges-spr1\",\"bert-large-uncased-mix-24-edges-spr1\",\"bert-large-uncased-mix-00-edges-srl-conll2012\",\"bert-large-uncased-mix-24-edges-srl-conll2012\"],\"exp_type\":[\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\"],\"f1_errn95\":{\"__ndarray__\":\"7xGy8kEUhT9cVXKgpa58P9FvG+78fXE/u8XbWH+3ZD8/pJyOPmxwPxKAthfSa2U/BDxIKVt4XD8jeej8J3lVP4ARadS9DFM/xBc0rc9TRT+UV/HzuZSgPwW/sJsZ/ZY//Raog23khT/zGBAd4hyDP8o5e/X6/2U/4/fqW4MxXz8=\",\"dtype\":\"float64\",\"shape\":[16]},\"f1_score\":{\"__ndarray__\":\"h0ifJee/6T9anKVmrGvtP+226rN6Z+s/leWbCteQ7j84qlVL5f3sP4+pfJEmxO4/TYP5Vu+J5z86/azlltPrPzv98/7xUuw/1i/mrBLx7j9+4JYX+27jP/4H5GEp7+o/CR3aCB3a6D/5wlYKY8rqP5yWoAygBeo/U/TLKE9D7T8=\",\"dtype\":\"float64\",\"shape\":[16]},\"fn_count\":{\"__ndarray__\":\"AAAAAABElEAAAAAAAEB9QAAAAAAAWLJAAAAAAAA4lUAAAAAAAPCgQAAAAAAAaI1AAAAAANCn9EAAAAAAgB7hQAAAAADgYeJAAAAAAICNw0AAAAAAAGB9QAAAAAAAwGlAAAAAAADolkAAAAAAABiNQAAAAACAjdJAAAAAAIC5wEA=\",\"dtype\":\"float64\",\"shape\":[16]},\"fp_count\":{\"__ndarray__\":\"AAAAAADgi0AAAAAAAEB9QAAAAAAAzqBAAAAAAAA4i0AAAAAAABiZQAAAAAAAQINAAAAAAMCM4kAAAAAAgDreQAAAAADANNtAAAAAAIDbwUAAAAAAAKBkQAAAAAAAgFNAAAAAAAB4kUAAAAAAAACQQAAAAACAhcJAAAAAAAB5s0A=\",\"dtype\":\"float64\",\"shape\":[16]},\"headroom_frac\":[6.913581793170807,-0.012967003881791192,8.56590798945166,0.002148873429032305,15.800991949986932,-0.02562503503298699,5.3724983530608466,0.007074678879016351,10.641027426702427,-0.0009276700694607807,2.5908918439559843,0.023780632679324145,12.405534046105204,-0.03231217680545297,7.854243998170655,-0.018650709311520762],\"index\":[13,37,51,75,127,151,165,189,203,227,241,265,317,341,393,417],\"kl_unif\":{\"__ndarray__\":\"smln+9gk4z+yaWf72CTjP1N3S+bAZ/I/U3dL5sBn8j8q+1h8JLv5Pyr7WHwku/k/1wcJs1Mx+T/XBwmzUzH5PzxsaUbuhvk/PGxpRu6G+T8htlvbmwngPyG2W9ubCeA/Zn7/NR5c1T9mfv81HlzVP90KNk206fQ/3Qo2TbTp9D8=\",\"dtype\":\"float64\",\"shape\":[16]},\"label\":[\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\"],\"layer_num\":[\"00\",\"24\",\"00\",\"24\",\"00\",\"24\",\"00\",\"24\",\"00\",\"24\",\"00\",\"24\",\"00\",\"24\",\"00\",\"24\"],\"lex_score\":[0.804675649147854,0.804675649147854,0.8563817514420556,0.8563817514420556,0.905993125093409,0.905993125093409,0.7355877588962386,0.7355877588962386,0.8851251582672498,0.8851251582672498,0.6072974644403215,0.6072974644403215,0.7766251728907331,0.7766251728907331,0.8131866690279881,0.8131866690279881],\"max_layer_score\":[0.9210662080825451,0.9210662080825451,0.9563573468484775,0.9563573468484775,0.9633308623671856,0.9633308623671856,0.8725050198344678,0.8725050198344678,0.9683055808687488,0.9683055808687488,0.8416945373467113,0.8416945373467113,0.8392282958199357,0.8392282958199357,0.916721352852095,0.916721352852095],\"num_epochs\":{\"__ndarray__\":\"AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8=\",\"dtype\":\"float64\",\"shape\":[16]},\"num_steps\":{\"__ndarray__\":\"AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8=\",\"dtype\":\"float64\",\"shape\":[16]},\"precision\":{\"__ndarray__\":\"7n+9sg236j9anKVmrGvtP4dzhckZ8+w/G0aniTje7j9AH0XqRGftPwZ62T0NBO8/KsK00H4r6j/TXulZ2Q3sP3sXWmeU0ew/h2g9Wfb87j/0MTgfg/PnP09+JQbsAO0/n1lC5XCf6T9cBJOvrpXqP5QS0zAPwes/0gXTcnHw7T8=\",\"dtype\":\"float64\",\"shape\":[16]},\"precision_errn95\":{\"__ndarray__\":\"vnmb6AdIhD9cVXKgpa58PxZ4p4CUY28/oTlVesHmYj+dhsZN+ilvPw48OB2SlmM/HfEgYSwlWz+2aslY0hJVP3ZfPmzMJlI/C04CdonmRD+tiu1wCgChPzz4FTkzQpQ/a19aZodohT8rGKtXPlmDP8qKC2zDX2Q/MqnfztZUXD8=\",\"dtype\":\"float64\",\"shape\":[16]},\"pred_pos_count\":{\"__ndarray__\":\"AAAAAAAZtUAAAAAAAK62QAAAAABACdZAAAAAAMAL2EAAAAAAAFTTQAAAAABAj9NAAAAAADB0CUEAAAAAmKQOQQAAAACEGhFBAAAAAOSlEUEAAAAAAICEQAAAAAAACIpAAAAAAADqtUAAAAAAAKO3QAAAAADwcvFAAAAAAADm8kA=\",\"dtype\":\"float64\",\"shape\":[16]},\"prev_layer_score\":[0.0,0.9209029674530029,0.0,0.9549658298492432,0.0,0.962913453578949,0.0,0.868610143661499,0.0,0.9670050144195557,0.0,0.8361204266548157,0.0,0.8392282724380493,0.0,0.9163974523544312],\"prev_score_max\":{\"__ndarray__\":\"AAAAAAAAAAAAAADgX3ntPwAAAAAAAAAAAAAAwHqa7j8AAAAAAAAAAAAAAECb0+4/AAAAAAAAAAAAAACgj+vrPwAAAAAAAAAAAAAAAFz87j8AAAAAAAAAAAAAACDk6uo/AAAAAAAAAAAAAABA9drqPwAAAAAAAAAAAAAAAMhV7T8=\",\"dtype\":\"float64\",\"shape\":[16]},\"real_delta_score\":[0.804675649147854,-0.0015092368295099856,0.8563817514420556,0.0002148349005205441,0.905993125093409,-0.0014692815263527281,0.7355877588962386,0.0009686456541324606,0.8851251582672498,-7.716398841250971e-05,0.6072974644403215,0.005574110691895617,0.7766251728907331,-0.0020228431766619037,0.8131866690279881,-0.0019309952916636286],\"real_headroom_frac\":[6.913581793170807,-0.012967003881791192,8.56590798945166,0.002148873429032305,15.800991949986932,-0.02562503503298699,5.3724983530608466,0.007074678879016351,10.641027426702427,-0.0009276700694607807,2.5908918439559843,0.023780632679324145,12.405534046105204,-0.03231217680545297,7.854243998170655,-0.018650709311520762],\"recall\":{\"__ndarray__\":\"sRhYD/7Z6D9anKVmrGvtP/qMuqn0A+o/a1JivvVE7j/Zwj6BbpfsP7X4oRlFhe4/ZpkQlXBj5T+9mEp4RJrrP4i3WbeV2Os/XwyfHDjl7j8Ph0W7gVngP/sT9Wj2I+k/P4Fgv08g6D+o/ysA6v/qP09zZTVKfug/0F3NDNOd7D8=\",\"dtype\":\"float64\",\"shape\":[16]},\"recall_errn95\":{\"__ndarray__\":\"vOnbYjXxhT9cVXKgpa58PxJogsg+wXM/6QcuT//qZj9o5wVwDlxxP9E5t571oWc/iwHXJlnuXT8zxf27cuNVP0WxulegClQ/4ys4WqTFRT8IGEG3ky6gP/e4Gk61kZo/KEy76A5mhj+ludvz+eGCP7heeM5i6Gc/imcSrGxZYT8=\",\"dtype\":\"float64\",\"shape\":[16]},\"run\":[\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-00-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-24-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-00-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-24-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-00-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-24-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-00-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-24-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-00-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-24-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-00-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-24-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-00-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-24-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-00-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-24-edges-srl-conll2012/run\"],\"score\":{\"__ndarray__\":\"h0ifJee/6T9anKVmrGvtP+226rN6Z+s/leWbCteQ7j84qlVL5f3sP4+pfJEmxO4/TYP5Vu+J5z86/azlltPrPzv98/7xUuw/1i/mrBLx7j9+4JYX+27jP/4H5GEp7+o/CR3aCB3a6D/5wlYKY8rqP5yWoAygBeo/U/TLKE9D7T8=\",\"dtype\":\"float64\",\"shape\":[16]},\"score_errn95\":{\"__ndarray__\":\"7xGy8kEUhT9cVXKgpa58P9FvG+78fXE/u8XbWH+3ZD8/pJyOPmxwPxKAthfSa2U/BDxIKVt4XD8jeej8J3lVP4ARadS9DFM/xBc0rc9TRT+UV/HzuZSgPwW/sJsZ/ZY//Raog23khT/zGBAd4hyDP8o5e/X6/2U/4/fqW4MxXz8=\",\"dtype\":\"float64\",\"shape\":[16]},\"seed\":[\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\"],\"split\":[\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\"],\"stratifier\":[\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\"],\"stratum_key\":{\"__ndarray__\":\"AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8=\",\"dtype\":\"float64\",\"shape\":[16]},\"tag\":[\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\"],\"task\":[\"coref-ontonotes-conll\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"rel-semeval\",\"spr1\",\"spr1\",\"srl-conll2012\",\"srl-conll2012\"],\"tn_count\":{\"__ndarray__\":\"AAAAAMAs00AAAAAAwJbTQAAAAADPvTJBAAAAAM/CMkEAAAAAeEMWQQAAAADwUhZBAAAAwFgUXEEAAADANxtcQQAAAAD48WlBAAAAgBv7aUEAAAAAABnTQAAAAADALtNAAAAAAADVx0AAAAAAAATIQAAAAIDVHUFBAAAAgJ4mQUE=\",\"dtype\":\"float64\",\"shape\":[16]},\"total_count\":{\"__ndarray__\":\"AAAAAEC32UAAAAAAQLfZQAAAAABMKDNBAAAAAEwoM0EAAAAAmJoXQQAAAACYmhdBAAAAgJkyXUEAAACAmTJdQQAAAAAujWpBAAAAAC6NakEAAAAAgDLUQAAAAACAMtRAAAAAAIDT0kAAAAAAgNPSQAAAAACIzkFBAAAAAIjOQUE=\",\"dtype\":\"float64\",\"shape\":[16]},\"tp_count\":{\"__ndarray__\":\"AAAAAACdsUAAAAAAANq0QAAAAACA79NAAAAAAAAy10AAAAAAgMLRQAAAAABA9dJAAAAAAADRBEEAAAAASN0KQQAAAABwzg5BAAAAAAgXEUEAAAAAALB+QAAAAAAAmIdAAAAAAACMsUAAAAAAAKOzQAAAAACARO5AAAAAAHCu8UA=\",\"dtype\":\"float64\",\"shape\":[16]},\"true_pos_count\":{\"__ndarray__\":\"AAAAAACutkAAAAAAAK62QAAAAACAhdhAAAAAAICF2EAAAAAAgODTQAAAAACA4NNAAAAAAOgkD0EAAAAA6CQPQQAAAAB0sxFBAAAAAHSzEUEAAAAAAAiOQAAAAAAACI5AAAAAAABGt0AAAAAAAEa3QAAAAACgxfNAAAAAAKDF80A=\",\"dtype\":\"float64\",\"shape\":[16]}},\"selected\":{\"id\":\"3918\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"3919\",\"type\":\"UnionRenderers\"}},\"id\":\"3783\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"range\":{\"id\":\"3706\",\"type\":\"FactorRange\"}},\"id\":\"3740\",\"type\":\"Dodge\"},{\"attributes\":{\"source\":{\"id\":\"3741\",\"type\":\"ColumnDataSource\"}},\"id\":\"3746\",\"type\":\"CDSView\"},{\"attributes\":{},\"id\":\"3923\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"align\":\"center\",\"plot\":null,\"text\":\"F1 Scores\"},\"id\":\"3751\",\"type\":\"Title\"},{\"attributes\":{},\"id\":\"3713\",\"type\":\"LinearScale\"},{\"attributes\":{\"plot\":{\"id\":\"3708\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"source\":{\"id\":\"3737\",\"type\":\"ColumnDataSource\"},\"text\":{\"field\":\"_formatted_exp_layer\"},\"text_align\":\"right\",\"text_baseline\":\"middle\",\"text_color\":{\"value\":\"White\"},\"text_font_size\":{\"value\":\"11pt\"},\"text_font_style\":\"bold\",\"x\":{\"field\":\"weight_exp_layer\"},\"x_offset\":{\"value\":-6},\"y\":{\"field\":\"_display_name\",\"transform\":{\"id\":\"3730\",\"type\":\"Dodge\"}}},\"id\":\"3738\",\"type\":\"LabelSet\"},{\"attributes\":{\"data_source\":{\"id\":\"3741\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"3743\",\"type\":\"HBar\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"3744\",\"type\":\"HBar\"},\"selection_glyph\":null,\"view\":{\"id\":\"3746\",\"type\":\"CDSView\"}},\"id\":\"3745\",\"type\":\"GlyphRenderer\"},{\"attributes\":{},\"id\":\"3715\",\"type\":\"CategoricalScale\"},{\"attributes\":{\"bottom_units\":\"screen\",\"fill_alpha\":{\"value\":0.5},\"fill_color\":{\"value\":\"lightgrey\"},\"left_units\":\"screen\",\"level\":\"overlay\",\"line_alpha\":{\"value\":1.0},\"line_color\":{\"value\":\"black\"},\"line_dash\":[4,4],\"line_width\":{\"value\":2},\"plot\":null,\"render_mode\":\"css\",\"right_units\":\"screen\",\"top_units\":\"screen\"},\"id\":\"3776\",\"type\":\"BoxAnnotation\"},{\"attributes\":{},\"id\":\"3718\",\"type\":\"BasicTicker\"},{\"attributes\":{\"callback\":null,\"data\":{\"_bar_center\":[\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\"],\"_bar_height\":[0.04303781222552061,0.02665954409167171,0.092449951171875,0.030033160373568537,0.09519200026988983,0.0938491590321064,0.09799955897033215,0.05106540396809578,0.09109024219214917],\"_display_name\":[\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\"],\"_formatted_entropy\":[\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\"],\"_formatted_exp_layer\":[\"15.80\",\"13.75\",\"13.16\",\"13.06\",\"11.68\",\"12.83\",\"12.72\",\"13.63\",\"13.01\"],\"_formatted_kl_unif\":[\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\"],\"checkpoint\":[\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\"],\"display_col\":[\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\"],\"exp_name\":[\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\"],\"exp_type\":[\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\"],\"gamma\":{\"__ndarray__\":\"AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/\",\"dtype\":\"float64\",\"shape\":[9]},\"index\":[9,10,11,12,13,14,15,16,17],\"label\":[\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\"],\"layer_num\":[1,1,1,1,1,1,1,1,1],\"layer_weight\":[0.015939930453896523,0.009873905219137669,0.03424072265625,0.01112339273095131,0.03525629639625549,0.03475894778966904,0.03629613295197487,0.018913112580776215,0.03373712673783302],\"run\":[\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\"],\"scalar_set\":[\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\"],\"tag\":[\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\"],\"task\":[\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\"],\"weight_entropy\":[4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481],\"weight_exp_layer\":{\"__ndarray__\":\"AABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipA\",\"dtype\":\"float64\",\"shape\":[9]},\"weight_exp_layer_oneplus\":{\"__ndarray__\":\"SG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytA\",\"dtype\":\"float64\",\"shape\":[9]},\"weight_kl_unif\":{\"__ndarray__\":\"w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/\",\"dtype\":\"float64\",\"shape\":[9]}},\"selected\":{\"id\":\"3920\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"3921\",\"type\":\"UnionRenderers\"}},\"id\":\"3731\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"height\":{\"value\":0.9},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"right\":{\"field\":\"exp_layer\"},\"y\":{\"field\":\"_display_name\",\"transform\":{\"id\":\"3740\",\"type\":\"Dodge\"}}},\"id\":\"3744\",\"type\":\"HBar\"},{\"attributes\":{},\"id\":\"3925\",\"type\":\"UnionRenderers\"},{\"attributes\":{},\"id\":\"3756\",\"type\":\"CategoricalScale\"},{\"attributes\":{\"axis_label_text_font_style\":\"bold\",\"formatter\":{\"id\":\"3913\",\"type\":\"BasicTickFormatter\"},\"major_label_text_font_size\":{\"value\":\"13pt\"},\"plot\":{\"id\":\"3708\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"ticker\":{\"id\":\"3718\",\"type\":\"BasicTicker\"}},\"id\":\"3717\",\"type\":\"LinearAxis\"},{\"attributes\":{\"above\":[{\"id\":\"3717\",\"type\":\"LinearAxis\"}],\"left\":[{\"id\":\"3722\",\"type\":\"CategoricalAxis\"}],\"min_border_bottom\":0,\"min_border_left\":0,\"min_border_right\":0,\"min_border_top\":0,\"plot_height\":320,\"plot_width\":270,\"renderers\":[{\"id\":\"3717\",\"type\":\"LinearAxis\"},{\"id\":\"3721\",\"type\":\"Grid\"},{\"id\":\"3722\",\"type\":\"CategoricalAxis\"},{\"id\":\"3725\",\"type\":\"Grid\"},{\"id\":\"3735\",\"type\":\"GlyphRenderer\"},{\"id\":\"3738\",\"type\":\"LabelSet\"},{\"id\":\"3745\",\"type\":\"GlyphRenderer\"},{\"id\":\"3748\",\"type\":\"LabelSet\"}],\"title\":{\"id\":\"3707\",\"type\":\"Title\"},\"toolbar\":{\"id\":\"3727\",\"type\":\"Toolbar\"},\"toolbar_location\":null,\"x_range\":{\"id\":\"3710\",\"type\":\"DataRange1d\"},\"x_scale\":{\"id\":\"3713\",\"type\":\"LinearScale\"},\"y_range\":{\"id\":\"3706\",\"type\":\"FactorRange\"},\"y_scale\":{\"id\":\"3715\",\"type\":\"CategoricalScale\"}},\"id\":\"3708\",\"subtype\":\"Figure\",\"type\":\"Plot\"},{\"attributes\":{},\"id\":\"3758\",\"type\":\"CategoricalScale\"},{\"attributes\":{\"plot\":{\"id\":\"3708\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"ticker\":{\"id\":\"3718\",\"type\":\"BasicTicker\"}},\"id\":\"3721\",\"type\":\"Grid\"},{\"attributes\":{\"callback\":null,\"data\":{\"_bar_center\":[\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\"],\"_bar_height\":[0.04303781222552061,0.02665954409167171,0.092449951171875,0.030033160373568537,0.09519200026988983,0.0938491590321064,0.09799955897033215,0.05106540396809578,0.09109024219214917],\"_display_name\":[\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\",\"Relations\"],\"_formatted_entropy\":[\"H(s) = 4.14 bits\",\"H(s) = 3.78 bits\",\"H(s) = 4.59 bits\",\"H(s) = 3.81 bits\",\"H(s) = 4.46 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.63 bits\",\"H(s) = 4.18 bits\",\"H(s) = 4.62 bits\"],\"_formatted_exp_layer\":[\"15.80\",\"13.75\",\"13.16\",\"13.06\",\"11.68\",\"12.83\",\"12.72\",\"13.63\",\"13.01\"],\"_formatted_kl_unif\":[\"K(s) = 0.50\",\"K(s) = 0.87\",\"K(s) = 0.06\",\"K(s) = 0.83\",\"K(s) = 0.19\",\"K(s) = 0.01\",\"K(s) = 0.01\",\"K(s) = 0.46\",\"K(s) = 0.02\"],\"checkpoint\":[\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\"],\"display_col\":[\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\",\"bert-large-uncased-mix (base)\"],\"exp_name\":[\"bert-large-uncased-mix-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-edges-ner-ontonotes\",\"bert-large-uncased-mix-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-edges-pos-ontonotes\",\"bert-large-uncased-mix-edges-rel-semeval\",\"bert-large-uncased-mix-edges-spr1\",\"bert-large-uncased-mix-edges-srl-conll2012\",\"bert-large-uncased-mix-edges-rel-semeval\"],\"exp_type\":[\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\"],\"gamma\":{\"__ndarray__\":\"AAAA4Oqa+j8AAADA7dADQAAAAGDJvfc/////X3nC/z8AAABAxFXqPwAAAMB0a/E/AAAAQMaA8T8AAADAl1wAQAAAAEBZU/I/\",\"dtype\":\"float64\",\"shape\":[9]},\"index\":[9,10,11,12,13,14,15,16,17],\"label\":[\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\"],\"layer_num\":[1,1,1,1,1,1,1,1,1],\"layer_weight\":[0.015939930453896523,0.009873905219137669,0.03424072265625,0.01112339273095131,0.03525629639625549,0.03475894778966904,0.03629613295197487,0.018913112580776215,0.03373712673783302],\"run\":[\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190218-mix-pre/bert-large-uncased-mix-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run\"],\"scalar_set\":[\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\",\"sent_encoder._text_field_embedder.scalar_mix.\"],\"tag\":[\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\"],\"task\":[\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\",\"rel-semeval\"],\"weight_entropy\":[4.140181005917806,3.7764824148321905,4.587601439374041,3.812007495159714,4.455960758924121,4.629625400112368,4.632143914051603,4.1792943322729315,4.6193263910481],\"weight_exp_layer\":{\"__ndarray__\":\"AABg9JKaL0AAAOB/yYErQAAAIHDNUipAAACI5TcgKkAAAGBIalonQAAA4A16qylAAACgq+ZyKUAAAHCE10MrQAAAwPSaBipA\",\"dtype\":\"float64\",\"shape\":[9]},\"weight_exp_layer_oneplus\":{\"__ndarray__\":\"SG0ancMRMEA4Vg4w3esrQLWuUZHZQitADHWfqOV+KkA6UODhV4QoQKJBQzxsmSpA8MJoWNtsKkAFr/O9DucrQL3UsjR/CytA\",\"dtype\":\"float64\",\"shape\":[9]},\"weight_kl_unif\":{\"__ndarray__\":\"w4hBHRwe4D9FuYi0hsHrPymHK1hlzaw/y9eQG4Ge6j+Leruj9QzIP6cer1P5JI0/RIrEm5r8hz/R4TV/YLvdP3BOql94Hpk/\",\"dtype\":\"float64\",\"shape\":[9]}},\"selected\":{\"id\":\"3922\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"3923\",\"type\":\"UnionRenderers\"}},\"id\":\"3737\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"axis_line_color\":{\"value\":null},\"formatter\":{\"id\":\"3909\",\"type\":\"CategoricalTickFormatter\"},\"major_label_text_font_size\":{\"value\":\"13pt\"},\"major_tick_line_color\":{\"value\":null},\"minor_tick_line_color\":{\"value\":null},\"plot\":{\"id\":\"3752\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"ticker\":{\"id\":\"3761\",\"type\":\"CategoricalTicker\"}},\"id\":\"3760\",\"type\":\"CategoricalAxis\"},{\"attributes\":{\"formatter\":{\"id\":\"3915\",\"type\":\"CategoricalTickFormatter\"},\"major_label_text_font_size\":{\"value\":\"0pt\"},\"major_tick_line_color\":{\"value\":null},\"plot\":{\"id\":\"3708\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"ticker\":{\"id\":\"3723\",\"type\":\"CategoricalTicker\"}},\"id\":\"3722\",\"type\":\"CategoricalAxis\"},{\"attributes\":{\"source\":{\"id\":\"3731\",\"type\":\"ColumnDataSource\"}},\"id\":\"3736\",\"type\":\"CDSView\"},{\"attributes\":{},\"id\":\"3922\",\"type\":\"Selection\"},{\"attributes\":{},\"id\":\"3761\",\"type\":\"CategoricalTicker\"},{\"attributes\":{},\"id\":\"3723\",\"type\":\"CategoricalTicker\"},{\"attributes\":{\"callback\":null,\"data\":{\"_bar_center\":[[\"Coref.\",-0.33901404143352976],[\"Deps.\",-0.15535020398162452],[\"Entities\",0.0],[\"Consts.\",0.0],[\"POS\",0.0],[\"Relations\",-0.2810097744404242],[\"SPR\",-0.4021549339653747],[\"SRL\",-0.4402286837439977]],\"_bar_height\":{\"__ndarray__\":\"7T+UGTCb1D8lNZ4Evg7mPwAAAAAAAPA/AAAAAAAA8D8AAAAAAADwP3MFdijfB9w/wZSxzl8MyT8B5x2RWJq+Pw==\",\"dtype\":\"float64\",\"shape\":[8]},\"_display_name\":[\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"Relations\",\"SPR\",\"SRL\"],\"_fill_color\":[\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\"],\"_formatted_exp_layer\":[\"9.47\",\"5.69\",\"4.64\",\"3.79\",\"3.39\",\"9.40\",\"9.93\",\"6.54\"],\"_formatted_kl_unif\":[\"K(\\u0394) = 0.60\",\"K(\\u0394) = 1.15\",\"K(\\u0394) = 1.61\",\"K(\\u0394) = 1.57\",\"K(\\u0394) = 1.60\",\"K(\\u0394) = 0.50\",\"K(\\u0394) = 0.33\",\"K(\\u0394) = 1.31\"],\"_line_color\":[\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\",\"#756bb1\"],\"accuracy\":{\"__ndarray__\":\"oB9HXNx57T8FFsSg89rvP//ZFX1Qx+8/aymEJd6V7z855byqzOPvPzcnkK3ZG+8/E01GLxS46z8VueqbtJ7vPw==\",\"dtype\":\"float64\",\"shape\":[8]},\"accuracy_errn95\":{\"__ndarray__\":\"I3yTc4araj+oo9ohfcQeP9htYP5dHzE/32/GaV4AFT8FDJMzuiEAPxKOJrH1XmI/GWL4AeGucz/PokNxgzciPw==\",\"dtype\":\"float64\",\"shape\":[8]},\"contextual_headroom\":[0.11639055893469108,0.09997559540642187,0.05733773727377656,0.1369172609382292,0.08318042260149905,0.23439707290638978,0.06260312292920267,0.10353468382410691],\"delta_score\":[0.013879441257917402,0.02552338412121402,0.02747614170542223,0.05941261708359613,0.03147784041096369,0.038022716937981205,0.0045373382940604445,0.004584003207641407],\"display_col\":[\"bert-large-uncased-mix-01 (base)\",\"bert-large-uncased-mix-01 (base)\",\"bert-large-uncased-mix-01 (base)\",\"bert-large-uncased-mix-01 (base)\",\"bert-large-uncased-mix-01 (base)\",\"bert-large-uncased-mix-01 (base)\",\"bert-large-uncased-mix-01 (base)\",\"bert-large-uncased-mix-01 (base)\"],\"display_row\":[\"coref-ontonotes-conll-1\",\"dep-labeling-ewt-_micro_avg_\",\"ner-ontonotes-_micro_avg_\",\"nonterminal-ontonotes-_micro_avg_\",\"pos-ontonotes-_micro_avg_\",\"rel-semeval-_clean_micro_\",\"spr1-_micro_avg_\",\"srl-conll2012-_clean_micro_\"],\"exp_layer\":[9.471179711705389,5.691932390197615,4.644666882875676,3.792980575634427,3.386439579545165,9.40046847774628,9.928992732451892,6.536649198760027],\"exp_name\":[\"bert-large-uncased-mix-01-edges-coref-ontonotes-conll\",\"bert-large-uncased-mix-01-edges-dep-labeling-ewt\",\"bert-large-uncased-mix-01-edges-ner-ontonotes\",\"bert-large-uncased-mix-01-edges-nonterminal-ontonotes\",\"bert-large-uncased-mix-01-edges-pos-ontonotes\",\"bert-large-uncased-mix-01-edges-rel-semeval\",\"bert-large-uncased-mix-01-edges-spr1\",\"bert-large-uncased-mix-01-edges-srl-conll2012\"],\"exp_type\":[\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\",\"bert-large-uncased-mix\"],\"f1_errn95\":{\"__ndarray__\":\"YbyXW15qhD+18UdmkO9vPzVmkoBF6Gs/XoZcAwvlWT/4KZkISH9QP4phtdNd+58/7W0xEZqbhT80oUgvMLZlPw==\",\"dtype\":\"float64\",\"shape\":[8]},\"f1_score\":{\"__ndarray__\":\"p0NJbJox6j/7roIqkTjsPw1xQeX63u0/iwDrqaRw6T84pOPQz1TtP0QeuIp2puQ/Ia/yfEj/6D8OkvtZLSvqPw==\",\"dtype\":\"float64\",\"shape\":[8]},\"fn_count\":{\"__ndarray__\":\"AAAAAACEkUAAAAAAAIquQAAAAAAAtJhAAAAAAOCw7kAAAAAAwAraQAAAAAAAUHtAAAAAAAAslUAAAAAAAFnSQA==\",\"dtype\":\"float64\",\"shape\":[8]},\"fp_count\":{\"__ndarray__\":\"AAAAAADgjUAAAAAAAKSbQAAAAAAAHJFAAAAAAGC64UAAAAAAgMHUQAAAAAAAYGFAAAAAAAAgk0AAAAAAAHLBQA==\",\"dtype\":\"float64\",\"shape\":[8]},\"headroom_frac\":[0.11924885819738537,0.2552961451987966,0.4791982211336487,0.43393080373117005,0.3784284742308631,0.16221498189598205,0.07247782669231503,0.04427504907852022],\"index\":[14,52,128,166,204,242,318,394],\"kl_unif\":{\"__ndarray__\":\"smln+9gk4z9Td0vmwGfyPyr7WHwku/k/1wcJs1Mx+T88bGlG7ob5PyG2W9ubCeA/Zn7/NR5c1T/dCjZNtOn0Pw==\",\"dtype\":\"float64\",\"shape\":[8]},\"label\":[\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\"],\"layer_num\":[\"01\",\"01\",\"01\",\"01\",\"01\",\"01\",\"01\",\"01\"],\"lex_score\":[0.804675649147854,0.8563817514420556,0.905993125093409,0.7355877588962386,0.8851251582672498,0.6072974644403215,0.7766251728907331,0.8131866690279881],\"max_layer_score\":[0.9210662080825451,0.9563573468484775,0.9633308623671856,0.8725050198344678,0.9683055808687488,0.8416945373467113,0.8392282958199357,0.916721352852095],\"num_epochs\":{\"__ndarray__\":\"AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fw==\",\"dtype\":\"float64\",\"shape\":[8]},\"num_steps\":{\"__ndarray__\":\"AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fw==\",\"dtype\":\"float64\",\"shape\":[8]},\"precision\":{\"__ndarray__\":\"UK7HUKyT6j9MNT3+GontP4lRXhaCPO4/MkW2mdXq6j+sfXgoOJztP5mFSpmFSuk/gzXqTzdH6T/sAICNTvvrPw==\",\"dtype\":\"float64\",\"shape\":[8]},\"precision_errn95\":{\"__ndarray__\":\"24dVEQ0NhD/uEi3FzT5sP/vOCt+z/mk/1b3EmfyMWD9mnKfLuKVPP0l5OzWrup8/D8TlLKZrhT8yQkh3CvNjPw==\",\"dtype\":\"float64\",\"shape\":[8]},\"pred_pos_count\":{\"__ndarray__\":\"AAAAAAAJtkAAAAAAgG7WQAAAAAAAZ9NAAAAAAEjnC0EAAAAA4F4RQQAAAAAAuIRAAAAAAADDtkAAAAAAoF3xQA==\",\"dtype\":\"float64\",\"shape\":[8]},\"prev_layer_score\":[0.8046756386756897,0.8563817739486694,0.9059931039810181,0.7355877757072449,0.8851251602172852,0.6072974801063538,0.7766251564025879,0.8131866455078125],\"prev_score_max\":{\"__ndarray__\":\"AAAAIOe/6T8AAADAemfrPwAAAEDl/ew/AAAAYO+J5z8AAAAA8lLsPwAAACD7buM/AAAAAB3a6D8AAAAAoAXqPw==\",\"dtype\":\"float64\",\"shape\":[8]},\"real_delta_score\":[0.013879441257917402,0.02552338412121402,0.02747614170542223,0.05941261708359613,0.03147784041096369,0.038022716937981205,0.0045373382940604445,0.004584003207641407],\"real_headroom_frac\":[0.11924885819738537,0.2552961451987966,0.4791982211336487,0.43393080373117005,0.3784284742308631,0.16221498189598205,0.07247782669231503,0.04427504907852022],\"recall\":{\"__ndarray__\":\"II//AlLS6T/oI73MtQTrP+Qmdmevg+0/oDmcEM4d6D86u6yrvA7tP614+1DQcuE/uuMiju646D+7h481iJPoPw==\",\"dtype\":\"float64\",\"shape\":[8]},\"recall_errn95\":{\"__ndarray__\":\"DsFbVSTLhD+ETeuhJ15yPzmuac6XH24/MFUELPNkWz9hBGI5CDtRP/jocTSNHqA/W0bajGbMhT/4UfsmxNBnPw==\",\"dtype\":\"float64\",\"shape\":[8]},\"run\":[\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-01-edges-coref-ontonotes-conll/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-01-edges-dep-labeling-ewt/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-01-edges-ner-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-01-edges-nonterminal-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-01-edges-pos-ontonotes/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-01-edges-rel-semeval/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-01-edges-spr1/run\",\"/nfs/jsalt/exp/edges-20190219-perlayer/bert-large-uncased-mix-01-edges-srl-conll2012/run\"],\"score\":{\"__ndarray__\":\"p0NJbJox6j/7roIqkTjsPw1xQeX63u0/iwDrqaRw6T84pOPQz1TtP0QeuIp2puQ/Ia/yfEj/6D8OkvtZLSvqPw==\",\"dtype\":\"float64\",\"shape\":[8]},\"score_errn95\":{\"__ndarray__\":\"YbyXW15qhD+18UdmkO9vPzVmkoBF6Gs/XoZcAwvlWT/4KZkISH9QP4phtdNd+58/7W0xEZqbhT80oUgvMLZlPw==\",\"dtype\":\"float64\",\"shape\":[8]},\"seed\":[\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\"],\"split\":[\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\"],\"stratifier\":[\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\"],\"stratum_key\":{\"__ndarray__\":\"AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fw==\",\"dtype\":\"float64\",\"shape\":[8]},\"tag\":[\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\"],\"task\":[\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"rel-semeval\",\"spr1\",\"srl-conll2012\"],\"tn_count\":{\"__ndarray__\":\"AAAAAMAc00AAAAAATb8yQQAAAAB0SxZBAAAAgP0VXEEAAACgMfVpQQAAAACAH9NAAAAAAACgx0AAAAAA6R5BQQ==\",\"dtype\":\"float64\",\"shape\":[8]},\"total_count\":{\"__ndarray__\":\"AAAAAEC32UAAAAAATCgzQQAAAACYmhdBAAAAgJkyXUEAAAAALo1qQQAAAACAMtRAAAAAAIDT0kAAAAAAiM5BQQ==\",\"dtype\":\"float64\",\"shape\":[8]},\"tp_count\":{\"__ndarray__\":\"AAAAAABNskAAAAAAQLTUQAAAAABAVdJAAAAAALB4B0EAAAAAyBIQQQAAAAAAYIBAAAAAAAD7sUAAAAAAwF7uQA==\",\"dtype\":\"float64\",\"shape\":[8]},\"true_pos_count\":{\"__ndarray__\":\"AAAAAACutkAAAAAAgIXYQAAAAACA4NNAAAAAAOgkD0EAAAAAdLMRQQAAAAAACI5AAAAAAABGt0AAAAAAoMXzQA==\",\"dtype\":\"float64\",\"shape\":[8]}},\"selected\":{\"id\":\"3924\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"3925\",\"type\":\"UnionRenderers\"}},\"id\":\"3741\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"data_source\":{\"id\":\"3731\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"3733\",\"type\":\"HBar\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"3734\",\"type\":\"HBar\"},\"selection_glyph\":null,\"view\":{\"id\":\"3736\",\"type\":\"CDSView\"}},\"id\":\"3735\",\"type\":\"GlyphRenderer\"},{\"attributes\":{},\"id\":\"3921\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"plot\":{\"id\":\"3752\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"ticker\":{\"id\":\"3761\",\"type\":\"CategoricalTicker\"},\"visible\":false},\"id\":\"3763\",\"type\":\"Grid\"},{\"attributes\":{\"dimension\":1,\"plot\":{\"id\":\"3708\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"ticker\":{\"id\":\"3723\",\"type\":\"CategoricalTicker\"}},\"id\":\"3725\",\"type\":\"Grid\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"height\":{\"value\":0.9},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"line_width\":{\"value\":1.5},\"right\":{\"field\":\"weight_exp_layer\"},\"y\":{\"field\":\"_display_name\",\"transform\":{\"id\":\"3730\",\"type\":\"Dodge\"}}},\"id\":\"3734\",\"type\":\"HBar\"},{\"attributes\":{},\"id\":\"3920\",\"type\":\"Selection\"},{\"attributes\":{\"axis_line_color\":{\"value\":null},\"formatter\":{\"id\":\"3911\",\"type\":\"CategoricalTickFormatter\"},\"major_label_text_font_size\":{\"value\":\"13pt\"},\"major_tick_line_color\":{\"value\":null},\"minor_tick_line_color\":{\"value\":null},\"plot\":{\"id\":\"3752\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"ticker\":{\"id\":\"3765\",\"type\":\"CategoricalTicker\"}},\"id\":\"3764\",\"type\":\"CategoricalAxis\"},{\"attributes\":{\"fill_color\":{\"value\":\"#3182bd\"},\"height\":{\"value\":0.9},\"line_color\":{\"value\":\"#3182bd\"},\"line_width\":{\"value\":1.5},\"right\":{\"field\":\"weight_exp_layer\"},\"y\":{\"field\":\"_display_name\",\"transform\":{\"id\":\"3730\",\"type\":\"Dodge\"}}},\"id\":\"3733\",\"type\":\"HBar\"},{\"attributes\":{},\"id\":\"3919\",\"type\":\"UnionRenderers\"},{\"attributes\":{},\"id\":\"3765\",\"type\":\"CategoricalTicker\"},{\"attributes\":{\"active_drag\":\"auto\",\"active_inspect\":\"auto\",\"active_multi\":null,\"active_scroll\":\"auto\",\"active_tap\":\"auto\",\"autohide\":true,\"tools\":[{\"id\":\"3726\",\"type\":\"SaveTool\"}]},\"id\":\"3727\",\"type\":\"Toolbar\"},{\"attributes\":{},\"id\":\"3918\",\"type\":\"Selection\"},{\"attributes\":{\"dimension\":1,\"plot\":{\"id\":\"3752\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"ticker\":{\"id\":\"3765\",\"type\":\"CategoricalTicker\"},\"visible\":false},\"id\":\"3767\",\"type\":\"Grid\"},{\"attributes\":{},\"id\":\"3726\",\"type\":\"SaveTool\"},{\"attributes\":{\"above\":[{\"id\":\"3760\",\"type\":\"CategoricalAxis\"}],\"background_fill_alpha\":{\"value\":0.8},\"background_fill_color\":{\"value\":\"#f2f2f2\"},\"left\":[{\"id\":\"3764\",\"type\":\"CategoricalAxis\"}],\"min_border_bottom\":0,\"min_border_left\":0,\"min_border_right\":5,\"min_border_top\":0,\"plot_height\":320,\"plot_width\":180,\"renderers\":[{\"id\":\"3760\",\"type\":\"CategoricalAxis\"},{\"id\":\"3763\",\"type\":\"Grid\"},{\"id\":\"3764\",\"type\":\"CategoricalAxis\"},{\"id\":\"3767\",\"type\":\"Grid\"},{\"id\":\"3776\",\"type\":\"BoxAnnotation\"},{\"id\":\"3784\",\"type\":\"LabelSet\"}],\"title\":{\"id\":\"3751\",\"type\":\"Title\"},\"toolbar\":{\"id\":\"3774\",\"type\":\"Toolbar\"},\"toolbar_location\":null,\"x_range\":{\"id\":\"3750\",\"type\":\"FactorRange\"},\"x_scale\":{\"id\":\"3756\",\"type\":\"CategoricalScale\"},\"y_range\":{\"id\":\"3706\",\"type\":\"FactorRange\"},\"y_scale\":{\"id\":\"3758\",\"type\":\"CategoricalScale\"}},\"id\":\"3752\",\"subtype\":\"Figure\",\"type\":\"Plot\"},{\"attributes\":{},\"id\":\"3915\",\"type\":\"CategoricalTickFormatter\"},{\"attributes\":{},\"id\":\"3927\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"callback\":null,\"factor_padding\":0.1,\"factors\":[\"Relations\",\"SPR\",\"Coref.\",\"SRL\",\"Entities\",\"Deps.\",\"Consts.\",\"POS\"],\"range_padding\":0.1,\"range_padding_units\":\"absolute\"},\"id\":\"3706\",\"type\":\"FactorRange\"},{\"attributes\":{},\"id\":\"3913\",\"type\":\"BasicTickFormatter\"},{\"attributes\":{\"fill_color\":{\"value\":\"#D5D2E7\"},\"height\":{\"value\":0.9},\"line_color\":{\"value\":\"#756bb1\"},\"right\":{\"field\":\"exp_layer\"},\"y\":{\"field\":\"_display_name\",\"transform\":{\"id\":\"3740\",\"type\":\"Dodge\"}}},\"id\":\"3743\",\"type\":\"HBar\"},{\"attributes\":{\"callback\":null,\"factors\":[\"\\u2113=0\",\"\\u2113=24\"]},\"id\":\"3750\",\"type\":\"FactorRange\"},{\"attributes\":{\"active_drag\":\"auto\",\"active_inspect\":\"auto\",\"active_multi\":null,\"active_scroll\":\"auto\",\"active_tap\":\"auto\",\"tools\":[{\"id\":\"3768\",\"type\":\"PanTool\"},{\"id\":\"3769\",\"type\":\"WheelZoomTool\"},{\"id\":\"3770\",\"type\":\"BoxZoomTool\"},{\"id\":\"3771\",\"type\":\"SaveTool\"},{\"id\":\"3772\",\"type\":\"ResetTool\"},{\"id\":\"3773\",\"type\":\"HelpTool\"}]},\"id\":\"3774\",\"type\":\"Toolbar\"}],\"root_ids\":[\"3786\"]},\"title\":\"Bokeh Application\",\"version\":\"1.0.4\"}};\n", - " var render_items = [{\"docid\":\"d00e8a36-a6fd-4ba9-88b3-0b2d91d79ffa\",\"roots\":{\"3786\":\"79bd46c0-f372-452e-a591-a281f3e2f628\"}}];\n", - " root.Bokeh.embed.embed_items_notebook(docs_json, render_items);\n", - "\n", - " }\n", - " if (root.Bokeh !== undefined) {\n", - " embed_document(root);\n", - " } else {\n", - " var attempts = 0;\n", - " var timer = setInterval(function(root) {\n", - " if (root.Bokeh !== undefined) {\n", - " embed_document(root);\n", - " clearInterval(timer);\n", - " }\n", - " attempts++;\n", - " if (attempts > 100) {\n", - " console.log(\"Bokeh: ERROR: Unable to run BokehJS code because BokehJS library is missing\");\n", - " clearInterval(timer);\n", - " }\n", - " }, 10, root)\n", - " }\n", - "})(window);" - ], - "application/vnd.bokehjs_exec.v0+json": "" - }, - "metadata": { - "application/vnd.bokehjs_exec.v0+json": { - "id": "3786" - } - }, - "output_type": "display_data" - } - ], - "source": [ - "cats_range = bokeh.models.FactorRange(*cats, factor_padding=0.10, range_padding=0.10, range_padding_units='absolute')\n", - "layers_range = x_range = (-0.5, MAX_LAYER+0.5)\n", - "\n", - "# PLOT_WIDTH=450\n", - "# PLOT_WIDTH=260\n", - "P2_WIDTH = 180\n", - "PLOT_WIDTH = 450 - P2_WIDTH\n", - "# PLOT_HEIGHT=450\n", - "# BAR_HEIGHT=0.425\n", - "# BAR_DODGE=BAR_HEIGHT/2\n", - "PLOT_HEIGHT=320\n", - "BAR_HEIGHT=0.9\n", - "BAR_DODGE=0\n", - "\n", - "# WEIGHT_EXP_FIELD = 'weight_exp_layer_oneplus'\n", - "WEIGHT_EXP_FIELD = 'weight_exp_layer'\n", - "weight_df['_formatted_exp_layer'] = weight_df[WEIGHT_EXP_FIELD].map(lambda l: \"{:.02f}\".format(l))\n", - "\n", - "##\n", - "# Add second plot\n", - "p2 = bp.figure(plot_width=PLOT_WIDTH, plot_height=PLOT_HEIGHT, \n", - " y_range=cats_range,\n", - " x_axis_location=\"above\",\n", - " title=\"Expected layer & center-of-gravity\",\n", - " tools=['save'])\n", - "p2.title.align = \"center\"\n", - "p2.toolbar.autohide = True\n", - "p2.yaxis.major_tick_line_color = None\n", - "# p2.yaxis.major_label_text_font_size = \"0pt\"\n", - "# p2.xaxis.axis_label = \"Encoder Layer ℓ\"\n", - "p2.xaxis.axis_label_text_font_style = \"bold\"\n", - "\n", - "##\n", - "# Add bars for weight cog\n", - "mask = weight_df['layer_num'].astype(float) == 1\n", - "mask &= weight_df.exp_type == EXPT_TYPES[0]\n", - "sdf = weight_df[mask]\n", - "y = bokeh.transform.dodge(\"_display_name\", -BAR_DODGE, range=p2.y_range)\n", - "p2.hbar(y=y, left=0, right=WEIGHT_EXP_FIELD, height=BAR_HEIGHT,\n", - " fill_color=WEIGHT_COLORS[0], line_color=WEIGHT_COLORS[0],\n", - " line_width=1.5,\n", - " source=sdf)\n", - "# Add labels with expected layer\n", - "score_labels = bokeh.models.annotations.LabelSet(\n", - " y=y, x=WEIGHT_EXP_FIELD, text=\"_formatted_exp_layer\",\n", - " text_align=\"right\", text_baseline=\"middle\", y_offset=0,\n", - " x_offset=-6,\n", - "# text_color=SCORE_COLORS[0], \n", - " text_color=\"White\",\n", - " text_font_size=\"11pt\",\n", - " text_font_style=\"bold\",\n", - "# background_fill_color=\"White\", border_line_color=\"White\", border_line_width=5,\n", - " source=bokeh.models.ColumnDataSource(sdf))\n", - "p2.add_layout(score_labels)\n", - "\n", - "##\n", - "# Add bars for expected layer\n", - "sdf = score_df[score_df['layer_num'].astype(float) == 1]\n", - "y = bokeh.transform.dodge(\"_display_name\", BAR_DODGE, range=p2.y_range)\n", - "p2.hbar(y=y, left=0, right=\"exp_layer\", height=BAR_HEIGHT,\n", - "# fill_color=SCORE_COLORS[0], \n", - " line_color=SCORE_COLORS[0], \n", - " fill_color=\"#D5D2E7\",\n", - "# line_color=\"Black\",\n", - "# fill_alpha=0.3,\n", - " source=sdf)\n", - "score_labels = bokeh.models.annotations.LabelSet(\n", - " y=y, x=\"exp_layer\", text=\"_formatted_exp_layer\",\n", - " text_align=\"right\", text_baseline=\"middle\", y_offset=0,\n", - " x_offset=-6,\n", - "# text_color=SCORE_COLORS[0], \n", - "# text_color=\"White\",\n", - " text_color=\"Black\",\n", - " text_font_size=\"11pt\",\n", - " text_font_style=\"bold\",\n", - "# background_fill_color=\"White\",\n", - "# border_line_color=\"White\", border_line_width=5,\n", - " source=bokeh.models.ColumnDataSource(sdf))\n", - "p2.add_layout(score_labels)\n", - "\n", - "p2.x_range.start = 0\n", - "\n", - "_FONT_SIZE = \"13pt\"\n", - "# p2.yaxis.major_label_text_font_size = _FONT_SIZE\n", - "p2.yaxis.major_label_text_font_size = \"0pt\"\n", - "p2.xaxis.major_label_text_font_size = _FONT_SIZE\n", - "\n", - "p2.min_border_left = 0\n", - "p2.min_border_right = 0\n", - "p2.min_border_top = 0\n", - "p2.min_border_bottom = 0\n", - "p2.toolbar_location = None\n", - "\n", - "##\n", - "# Side plot with bottom and top layer scores\n", - "score_df['_formatted_score'] = score_df['score'].map(lambda h: \"{:.1f}\".format(100*h))\n", - "score_df[\"_formatted_layer_num\"] = score_df[\"layer_num\"].map(lambda l: \"ℓ={:d}\".format(int(l)))\n", - "mask = score_df['layer_num'].map(lambda l: int(l) in {0, MAX_LAYER})\n", - "sdf = score_df[mask]\n", - "\n", - "x_range = bokeh.models.FactorRange(*sdf['_formatted_layer_num'].unique())\n", - "p4 = bp.figure(x_range=x_range, y_range=p2.y_range, plot_width=P2_WIDTH, plot_height=PLOT_HEIGHT,\n", - " x_axis_location=\"above\", title=\"F1 Scores\")\n", - "# Add labels with bottom-layer score\n", - "\n", - "score_labels = bokeh.models.annotations.LabelSet(\n", - " y=\"_display_name\", x='_formatted_layer_num', text=\"_formatted_score\",\n", - " text_align=\"center\", text_baseline=\"middle\",\n", - " source=bokeh.models.ColumnDataSource(sdf)\n", - ")\n", - "p4.add_layout(score_labels)\n", - "# # Add labels with top-layer score\n", - "# sdf = score_df[score_df['layer_num'].map(int) == MAX_LAYER]\n", - "# score_labels = bokeh.models.annotations.LabelSet(\n", - "# y=\"_display_name\", x='layer_num', text=\"_formatted_score\",\n", - "# text_align=\"center\", text_baseline=\"middle\",\n", - "# source=bokeh.models.ColumnDataSource(sdf)\n", - "# )\n", - "# p4.add_layout(score_labels)\n", - "\n", - "# p4.yaxis.major_label_text_font_size = \"0pt\"\n", - "p4.yaxis.major_label_text_font_size = _FONT_SIZE\n", - "p4.xaxis.major_label_text_font_size = _FONT_SIZE\n", - "p4.yaxis.major_tick_line_color = None\n", - "p4.yaxis.minor_tick_line_color = None\n", - "p4.xaxis.major_tick_line_color = None\n", - "p4.xaxis.minor_tick_line_color = None\n", - "p4.ygrid.visible = False\n", - "p4.xgrid.visible = False\n", - "p4.yaxis.axis_line_color = None\n", - "p4.xaxis.axis_line_color = None\n", - "p4.title.align = \"center\"\n", - "p4.toolbar_location = None\n", - "p4.min_border_left = 0\n", - "p4.min_border_right = 5 # add a little padding for visual aid\n", - "p4.min_border_top = 0\n", - "p4.min_border_bottom = 0\n", - "\n", - "bgbar_color = \"#f2f2f2\"\n", - "p4.background_fill_color = bgbar_color\n", - "p4.background_fill_alpha = 0.80\n", - "\n", - "# p2.xaxis.bounds = (0, 17)\n", - "\n", - "# p = p2\n", - "# p = p4\n", - "# p = bokeh.layouts.Row(p2, p4)\n", - "p = bokeh.layouts.Row(p4, p2)\n", - "bp.show(p)" - ] - }, - { - "cell_type": "code", - "execution_count": 35, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Copying file:///tmp/bert-large-uncased.exp_layer.20190603.211912.html [Content-Type=text/html]...\n", - "/ [1 files][ 52.9 KiB/ 52.9 KiB] \n", - "Operation completed over 1 objects/52.9 KiB. \n", - "Updated ACL on gs://edge-probing/iftenney/plots/bert-large-uncased.exp_layer.20190603.211912.html\n", - "Public URL: https://storage.googleapis.com/edge-probing/iftenney/plots/bert-large-uncased.exp_layer.20190603.211912.html\n" - ] - }, - { - "data": { - "text/plain": [ - "'https://storage.googleapis.com/edge-probing/iftenney/plots/bert-large-uncased.exp_layer.20190603.211912.html'" - ] - }, - "execution_count": 35, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "_save_figure_to_bucket(p, name=f\"{MODEL_NAME}.exp_layer\" + (\".running_max\" if USE_RUNNING_MAX else \"\"),\n", - " title=f\"{MODEL_NAME} expected layer and mixing CoG\" + (\" (running_max)\" if USE_RUNNING_MAX else \"\"))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Old plotting code, look at labels or strata within a task" - ] - }, - { - "cell_type": "code", - "execution_count": 36, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "task,exp_type,label,exp_layer\n", - "dep-labeling-ewt,bert-large-uncased-mix,_micro_avg_,5.691932390197615\n", - "\n" - ] - } - ], - "source": [ - "mask = fdf['layer_num'].astype(float) == 0\n", - "mask &= fdf['task'] == 'dep-labeling-ewt'\n", - "mask &= fdf['exp_type'] == 'bert-large-uncased-mix'\n", - "cols = ['task', 'exp_type', 'label', 'exp_layer']\n", - "print(fdf[mask][cols].to_csv(index=False,**csv_args))" - ] - }, - { - "cell_type": "code", - "execution_count": 37, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "task,exp_type,label,exp_layer\n", - "nonterminal-ontonotes,bert-large-uncased-mix,_micro_avg_,3.792980575634427\n", - "\n" - ] - } - ], - "source": [ - "mask = fdf['layer_num'].astype(float) == 0\n", - "mask &= fdf['task'] == 'nonterminal-ontonotes'\n", - "mask &= fdf['exp_type'] == 'bert-large-uncased-mix'\n", - "cols = ['task', 'exp_type', 'label', 'exp_layer']\n", - "print(fdf[mask][cols].to_csv(index=False,**csv_args))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Plot scalar mix for ELMo" - ] - }, - { - "cell_type": "code", - "execution_count": 43, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
tagexp_nameexp_typetaskcheckpointgammalabelrunscalar_setdisplay_col...weight_kl_unifweight_exp_layerweight_exp_layer_onepluslayer_numlayer_weight_display_name_bar_height_bar_center_formatted_entropy_formatted_kl_unif
0baseelmo-full-edges-coref-ontonotes-conllelmo-fullcoref-ontonotes-conll/model_state_eval_best.th2.094788Noneelmo-full-edges-coref-ontonotes-conll/runsent_encoder._text_field_embedder.token_embedd...elmo-full (base)...0.0997610.8736511.27974100.317322Coref.0.666376Coref.H(s) = 1.49 bitsK(s) = 0.10
1baseelmo-full-edges-dep-labeling-ewtelmo-fulldep-labeling-ewt/model_state_eval_best.th3.233000Noneelmo-full-edges-dep-labeling-ewt/runsent_encoder._text_field_embedder.token_embedd...elmo-full (base)...0.8212921.0010221.08223000.0750376Deps.0.157579Deps.H(s) = 0.76 bitsK(s) = 0.82
2baseelmo-full-edges-ner-ontonoteselmo-fullner-ontonotes/model_state_eval_best.th2.308605Noneelmo-full-edges-ner-ontonotes/runsent_encoder._text_field_embedder.token_embedd...elmo-full (base)...0.0358710.9660251.37561400.29775Entities0.625275EntitiesH(s) = 1.55 bitsK(s) = 0.04
3baseelmo-full-edges-nonterminal-ontonoteselmo-fullnonterminal-ontonotes/model_state_eval_best.th2.295377Noneelmo-full-edges-nonterminal-ontonotes/runsent_encoder._text_field_embedder.token_embedd...elmo-full (base)...0.7701210.9968551.08902400.0846346Consts.0.177733Consts.H(s) = 0.81 bitsK(s) = 0.77
4baseelmo-full-edges-pos-ontonoteselmo-fullpos-ontonotes/model_state_eval_best.th0.768965Noneelmo-full-edges-pos-ontonotes/runsent_encoder._text_field_embedder.token_embedd...elmo-full (base)...0.1371340.8074291.23747800.347521POS0.729793POSH(s) = 1.45 bitsK(s) = 0.14
5baseelmo-full-edges-spr1elmo-fullspr1/model_state_eval_best.th1.035713Noneelmo-full-edges-spr1/runsent_encoder._text_field_embedder.token_embedd...elmo-full (base)...0.0033841.0185381.47351200.308769SPR0.648414SPRH(s) = 1.58 bitsK(s) = 0.00
6baseelmo-full-edges-srl-conll2012elmo-fullsrl-conll2012/model_state_eval_best.th2.064842Noneelmo-full-edges-srl-conll2012/runsent_encoder._text_field_embedder.token_embedd...elmo-full (base)...0.4751750.9681791.14054000.151122SRL0.317356SRLH(s) = 1.11 bitsK(s) = 0.48
7baseelmo-full-edges-rel-semevalelmo-fullrel-semeval/model_state_eval_best.th1.068652None/nfs/jsalt/exp/edges-20190205-semeval/elmo-ful...sent_encoder._text_field_embedder.token_embedd...elmo-full (base)...0.0069731.0685831.49989600.287562Relations0.60388RelationsH(s) = 1.58 bitsK(s) = 0.01
8baseelmo-full-edges-coref-ontonotes-conllelmo-fullcoref-ontonotes-conll/model_state_eval_best.th2.094788Noneelmo-full-edges-coref-ontonotes-conll/runsent_encoder._text_field_embedder.token_embedd...elmo-full (base)...0.0997610.8736511.27974110.491705Coref.1.03258Coref.H(s) = 1.49 bitsK(s) = 0.10
9baseelmo-full-edges-dep-labeling-ewtelmo-fulldep-labeling-ewt/model_state_eval_best.th3.233000Noneelmo-full-edges-dep-labeling-ewt/runsent_encoder._text_field_embedder.token_embedd...elmo-full (base)...0.8212921.0010221.08223010.848903Deps.1.7827Deps.H(s) = 0.76 bitsK(s) = 0.82
10baseelmo-full-edges-ner-ontonoteselmo-fullner-ontonotes/model_state_eval_best.th2.308605Noneelmo-full-edges-ner-ontonotes/runsent_encoder._text_field_embedder.token_embedd...elmo-full (base)...0.0358710.9660251.37561410.438475Entities0.920797EntitiesH(s) = 1.55 bitsK(s) = 0.04
11baseelmo-full-edges-nonterminal-ontonoteselmo-fullnonterminal-ontonotes/model_state_eval_best.th2.295377Noneelmo-full-edges-nonterminal-ontonotes/runsent_encoder._text_field_embedder.token_embedd...elmo-full (base)...0.7701210.9968551.08902410.833876Consts.1.75114Consts.H(s) = 0.81 bitsK(s) = 0.77
12baseelmo-full-edges-pos-ontonoteselmo-fullpos-ontonotes/model_state_eval_best.th0.768965Noneelmo-full-edges-pos-ontonotes/runsent_encoder._text_field_embedder.token_embedd...elmo-full (base)...0.1371340.8074291.23747810.49753POS1.04481POSH(s) = 1.45 bitsK(s) = 0.14
13baseelmo-full-edges-spr1elmo-fullspr1/model_state_eval_best.th1.035713Noneelmo-full-edges-spr1/runsent_encoder._text_field_embedder.token_embedd...elmo-full (base)...0.0033841.0185381.47351210.363925SPR0.764243SPRH(s) = 1.58 bitsK(s) = 0.00
14baseelmo-full-edges-srl-conll2012elmo-fullsrl-conll2012/model_state_eval_best.th2.064842Noneelmo-full-edges-srl-conll2012/runsent_encoder._text_field_embedder.token_embedd...elmo-full (base)...0.4751750.9681791.14054010.729577SRL1.53211SRLH(s) = 1.11 bitsK(s) = 0.48
15baseelmo-full-edges-rel-semevalelmo-fullrel-semeval/model_state_eval_best.th1.068652None/nfs/jsalt/exp/edges-20190205-semeval/elmo-ful...sent_encoder._text_field_embedder.token_embedd...elmo-full (base)...0.0069731.0685831.49989610.356293Relations0.748216RelationsH(s) = 1.58 bitsK(s) = 0.01
16baseelmo-full-edges-coref-ontonotes-conllelmo-fullcoref-ontonotes-conll/model_state_eval_best.th2.094788Noneelmo-full-edges-coref-ontonotes-conll/runsent_encoder._text_field_embedder.token_embedd...elmo-full (base)...0.0997610.8736511.27974120.190973Coref.0.401043Coref.H(s) = 1.49 bitsK(s) = 0.10
17baseelmo-full-edges-dep-labeling-ewtelmo-fulldep-labeling-ewt/model_state_eval_best.th3.233000Noneelmo-full-edges-dep-labeling-ewt/runsent_encoder._text_field_embedder.token_embedd...elmo-full (base)...0.8212921.0010221.08223020.0760595Deps.0.159725Deps.H(s) = 0.76 bitsK(s) = 0.82
18baseelmo-full-edges-ner-ontonoteselmo-fullner-ontonotes/model_state_eval_best.th2.308605Noneelmo-full-edges-ner-ontonotes/runsent_encoder._text_field_embedder.token_embedd...elmo-full (base)...0.0358710.9660251.37561420.263775Entities0.553928EntitiesH(s) = 1.55 bitsK(s) = 0.04
19baseelmo-full-edges-nonterminal-ontonoteselmo-fullnonterminal-ontonotes/model_state_eval_best.th2.295377Noneelmo-full-edges-nonterminal-ontonotes/runsent_encoder._text_field_embedder.token_embedd...elmo-full (base)...0.7701210.9968551.08902420.0814892Consts.0.171127Consts.H(s) = 0.81 bitsK(s) = 0.77
20baseelmo-full-edges-pos-ontonoteselmo-fullpos-ontonotes/model_state_eval_best.th0.768965Noneelmo-full-edges-pos-ontonotes/runsent_encoder._text_field_embedder.token_embedd...elmo-full (base)...0.1371340.8074291.23747820.154949POS0.325394POSH(s) = 1.45 bitsK(s) = 0.14
21baseelmo-full-edges-spr1elmo-fullspr1/model_state_eval_best.th1.035713Noneelmo-full-edges-spr1/runsent_encoder._text_field_embedder.token_embedd...elmo-full (base)...0.0033841.0185381.47351220.327306SPR0.687343SPRH(s) = 1.58 bitsK(s) = 0.00
22baseelmo-full-edges-srl-conll2012elmo-fullsrl-conll2012/model_state_eval_best.th2.064842Noneelmo-full-edges-srl-conll2012/runsent_encoder._text_field_embedder.token_embedd...elmo-full (base)...0.4751750.9681791.14054020.119301SRL0.250532SRLH(s) = 1.11 bitsK(s) = 0.48
23baseelmo-full-edges-rel-semevalelmo-fullrel-semeval/model_state_eval_best.th1.068652None/nfs/jsalt/exp/edges-20190205-semeval/elmo-ful...sent_encoder._text_field_embedder.token_embedd...elmo-full (base)...0.0069731.0685831.49989620.356145Relations0.747904RelationsH(s) = 1.58 bitsK(s) = 0.01
24baseelmo-full-edges-coref-ontonotes-conllelmo-fullcoref-ontonotes-conll/model_state_eval_best.th2.094788Noneelmo-full-edges-coref-ontonotes-conll/runsent_encoder._text_field_embedder.token_embedd...elmo-full (base)...0.0997610.8736511.27974130Coref.0Coref.H(s) = 1.49 bitsK(s) = 0.10
25baseelmo-full-edges-dep-labeling-ewtelmo-fulldep-labeling-ewt/model_state_eval_best.th3.233000Noneelmo-full-edges-dep-labeling-ewt/runsent_encoder._text_field_embedder.token_embedd...elmo-full (base)...0.8212921.0010221.08223030Deps.0Deps.H(s) = 0.76 bitsK(s) = 0.82
26baseelmo-full-edges-ner-ontonoteselmo-fullner-ontonotes/model_state_eval_best.th2.308605Noneelmo-full-edges-ner-ontonotes/runsent_encoder._text_field_embedder.token_embedd...elmo-full (base)...0.0358710.9660251.37561430Entities0EntitiesH(s) = 1.55 bitsK(s) = 0.04
27baseelmo-full-edges-nonterminal-ontonoteselmo-fullnonterminal-ontonotes/model_state_eval_best.th2.295377Noneelmo-full-edges-nonterminal-ontonotes/runsent_encoder._text_field_embedder.token_embedd...elmo-full (base)...0.7701210.9968551.08902430Consts.0Consts.H(s) = 0.81 bitsK(s) = 0.77
28baseelmo-full-edges-pos-ontonoteselmo-fullpos-ontonotes/model_state_eval_best.th0.768965Noneelmo-full-edges-pos-ontonotes/runsent_encoder._text_field_embedder.token_embedd...elmo-full (base)...0.1371340.8074291.23747830POS0POSH(s) = 1.45 bitsK(s) = 0.14
29baseelmo-full-edges-spr1elmo-fullspr1/model_state_eval_best.th1.035713Noneelmo-full-edges-spr1/runsent_encoder._text_field_embedder.token_embedd...elmo-full (base)...0.0033841.0185381.47351230SPR0SPRH(s) = 1.58 bitsK(s) = 0.00
..................................................................
170baseelmo-full-edges-ner-ontonoteselmo-fullner-ontonotes/model_state_eval_best.th2.308605Noneelmo-full-edges-ner-ontonotes/runsent_encoder._text_field_embedder.token_embedd...elmo-full (base)...0.0358710.9660251.375614210Entities0EntitiesH(s) = 1.55 bitsK(s) = 0.04
171baseelmo-full-edges-nonterminal-ontonoteselmo-fullnonterminal-ontonotes/model_state_eval_best.th2.295377Noneelmo-full-edges-nonterminal-ontonotes/runsent_encoder._text_field_embedder.token_embedd...elmo-full (base)...0.7701210.9968551.089024210Consts.0Consts.H(s) = 0.81 bitsK(s) = 0.77
172baseelmo-full-edges-pos-ontonoteselmo-fullpos-ontonotes/model_state_eval_best.th0.768965Noneelmo-full-edges-pos-ontonotes/runsent_encoder._text_field_embedder.token_embedd...elmo-full (base)...0.1371340.8074291.237478210POS0POSH(s) = 1.45 bitsK(s) = 0.14
173baseelmo-full-edges-spr1elmo-fullspr1/model_state_eval_best.th1.035713Noneelmo-full-edges-spr1/runsent_encoder._text_field_embedder.token_embedd...elmo-full (base)...0.0033841.0185381.473512210SPR0SPRH(s) = 1.58 bitsK(s) = 0.00
174baseelmo-full-edges-srl-conll2012elmo-fullsrl-conll2012/model_state_eval_best.th2.064842Noneelmo-full-edges-srl-conll2012/runsent_encoder._text_field_embedder.token_embedd...elmo-full (base)...0.4751750.9681791.140540210SRL0SRLH(s) = 1.11 bitsK(s) = 0.48
175baseelmo-full-edges-rel-semevalelmo-fullrel-semeval/model_state_eval_best.th1.068652None/nfs/jsalt/exp/edges-20190205-semeval/elmo-ful...sent_encoder._text_field_embedder.token_embedd...elmo-full (base)...0.0069731.0685831.499896210Relations0RelationsH(s) = 1.58 bitsK(s) = 0.01
176baseelmo-full-edges-coref-ontonotes-conllelmo-fullcoref-ontonotes-conll/model_state_eval_best.th2.094788Noneelmo-full-edges-coref-ontonotes-conll/runsent_encoder._text_field_embedder.token_embedd...elmo-full (base)...0.0997610.8736511.279741220Coref.0Coref.H(s) = 1.49 bitsK(s) = 0.10
177baseelmo-full-edges-dep-labeling-ewtelmo-fulldep-labeling-ewt/model_state_eval_best.th3.233000Noneelmo-full-edges-dep-labeling-ewt/runsent_encoder._text_field_embedder.token_embedd...elmo-full (base)...0.8212921.0010221.082230220Deps.0Deps.H(s) = 0.76 bitsK(s) = 0.82
178baseelmo-full-edges-ner-ontonoteselmo-fullner-ontonotes/model_state_eval_best.th2.308605Noneelmo-full-edges-ner-ontonotes/runsent_encoder._text_field_embedder.token_embedd...elmo-full (base)...0.0358710.9660251.375614220Entities0EntitiesH(s) = 1.55 bitsK(s) = 0.04
179baseelmo-full-edges-nonterminal-ontonoteselmo-fullnonterminal-ontonotes/model_state_eval_best.th2.295377Noneelmo-full-edges-nonterminal-ontonotes/runsent_encoder._text_field_embedder.token_embedd...elmo-full (base)...0.7701210.9968551.089024220Consts.0Consts.H(s) = 0.81 bitsK(s) = 0.77
180baseelmo-full-edges-pos-ontonoteselmo-fullpos-ontonotes/model_state_eval_best.th0.768965Noneelmo-full-edges-pos-ontonotes/runsent_encoder._text_field_embedder.token_embedd...elmo-full (base)...0.1371340.8074291.237478220POS0POSH(s) = 1.45 bitsK(s) = 0.14
181baseelmo-full-edges-spr1elmo-fullspr1/model_state_eval_best.th1.035713Noneelmo-full-edges-spr1/runsent_encoder._text_field_embedder.token_embedd...elmo-full (base)...0.0033841.0185381.473512220SPR0SPRH(s) = 1.58 bitsK(s) = 0.00
182baseelmo-full-edges-srl-conll2012elmo-fullsrl-conll2012/model_state_eval_best.th2.064842Noneelmo-full-edges-srl-conll2012/runsent_encoder._text_field_embedder.token_embedd...elmo-full (base)...0.4751750.9681791.140540220SRL0SRLH(s) = 1.11 bitsK(s) = 0.48
183baseelmo-full-edges-rel-semevalelmo-fullrel-semeval/model_state_eval_best.th1.068652None/nfs/jsalt/exp/edges-20190205-semeval/elmo-ful...sent_encoder._text_field_embedder.token_embedd...elmo-full (base)...0.0069731.0685831.499896220Relations0RelationsH(s) = 1.58 bitsK(s) = 0.01
184baseelmo-full-edges-coref-ontonotes-conllelmo-fullcoref-ontonotes-conll/model_state_eval_best.th2.094788Noneelmo-full-edges-coref-ontonotes-conll/runsent_encoder._text_field_embedder.token_embedd...elmo-full (base)...0.0997610.8736511.279741230Coref.0Coref.H(s) = 1.49 bitsK(s) = 0.10
185baseelmo-full-edges-dep-labeling-ewtelmo-fulldep-labeling-ewt/model_state_eval_best.th3.233000Noneelmo-full-edges-dep-labeling-ewt/runsent_encoder._text_field_embedder.token_embedd...elmo-full (base)...0.8212921.0010221.082230230Deps.0Deps.H(s) = 0.76 bitsK(s) = 0.82
186baseelmo-full-edges-ner-ontonoteselmo-fullner-ontonotes/model_state_eval_best.th2.308605Noneelmo-full-edges-ner-ontonotes/runsent_encoder._text_field_embedder.token_embedd...elmo-full (base)...0.0358710.9660251.375614230Entities0EntitiesH(s) = 1.55 bitsK(s) = 0.04
187baseelmo-full-edges-nonterminal-ontonoteselmo-fullnonterminal-ontonotes/model_state_eval_best.th2.295377Noneelmo-full-edges-nonterminal-ontonotes/runsent_encoder._text_field_embedder.token_embedd...elmo-full (base)...0.7701210.9968551.089024230Consts.0Consts.H(s) = 0.81 bitsK(s) = 0.77
188baseelmo-full-edges-pos-ontonoteselmo-fullpos-ontonotes/model_state_eval_best.th0.768965Noneelmo-full-edges-pos-ontonotes/runsent_encoder._text_field_embedder.token_embedd...elmo-full (base)...0.1371340.8074291.237478230POS0POSH(s) = 1.45 bitsK(s) = 0.14
189baseelmo-full-edges-spr1elmo-fullspr1/model_state_eval_best.th1.035713Noneelmo-full-edges-spr1/runsent_encoder._text_field_embedder.token_embedd...elmo-full (base)...0.0033841.0185381.473512230SPR0SPRH(s) = 1.58 bitsK(s) = 0.00
190baseelmo-full-edges-srl-conll2012elmo-fullsrl-conll2012/model_state_eval_best.th2.064842Noneelmo-full-edges-srl-conll2012/runsent_encoder._text_field_embedder.token_embedd...elmo-full (base)...0.4751750.9681791.140540230SRL0SRLH(s) = 1.11 bitsK(s) = 0.48
191baseelmo-full-edges-rel-semevalelmo-fullrel-semeval/model_state_eval_best.th1.068652None/nfs/jsalt/exp/edges-20190205-semeval/elmo-ful...sent_encoder._text_field_embedder.token_embedd...elmo-full (base)...0.0069731.0685831.499896230Relations0RelationsH(s) = 1.58 bitsK(s) = 0.01
192baseelmo-full-edges-coref-ontonotes-conllelmo-fullcoref-ontonotes-conll/model_state_eval_best.th2.094788Noneelmo-full-edges-coref-ontonotes-conll/runsent_encoder._text_field_embedder.token_embedd...elmo-full (base)...0.0997610.8736511.279741240Coref.0Coref.H(s) = 1.49 bitsK(s) = 0.10
193baseelmo-full-edges-dep-labeling-ewtelmo-fulldep-labeling-ewt/model_state_eval_best.th3.233000Noneelmo-full-edges-dep-labeling-ewt/runsent_encoder._text_field_embedder.token_embedd...elmo-full (base)...0.8212921.0010221.082230240Deps.0Deps.H(s) = 0.76 bitsK(s) = 0.82
194baseelmo-full-edges-ner-ontonoteselmo-fullner-ontonotes/model_state_eval_best.th2.308605Noneelmo-full-edges-ner-ontonotes/runsent_encoder._text_field_embedder.token_embedd...elmo-full (base)...0.0358710.9660251.375614240Entities0EntitiesH(s) = 1.55 bitsK(s) = 0.04
195baseelmo-full-edges-nonterminal-ontonoteselmo-fullnonterminal-ontonotes/model_state_eval_best.th2.295377Noneelmo-full-edges-nonterminal-ontonotes/runsent_encoder._text_field_embedder.token_embedd...elmo-full (base)...0.7701210.9968551.089024240Consts.0Consts.H(s) = 0.81 bitsK(s) = 0.77
196baseelmo-full-edges-pos-ontonoteselmo-fullpos-ontonotes/model_state_eval_best.th0.768965Noneelmo-full-edges-pos-ontonotes/runsent_encoder._text_field_embedder.token_embedd...elmo-full (base)...0.1371340.8074291.237478240POS0POSH(s) = 1.45 bitsK(s) = 0.14
197baseelmo-full-edges-spr1elmo-fullspr1/model_state_eval_best.th1.035713Noneelmo-full-edges-spr1/runsent_encoder._text_field_embedder.token_embedd...elmo-full (base)...0.0033841.0185381.473512240SPR0SPRH(s) = 1.58 bitsK(s) = 0.00
198baseelmo-full-edges-srl-conll2012elmo-fullsrl-conll2012/model_state_eval_best.th2.064842Noneelmo-full-edges-srl-conll2012/runsent_encoder._text_field_embedder.token_embedd...elmo-full (base)...0.4751750.9681791.140540240SRL0SRLH(s) = 1.11 bitsK(s) = 0.48
199baseelmo-full-edges-rel-semevalelmo-fullrel-semeval/model_state_eval_best.th1.068652None/nfs/jsalt/exp/edges-20190205-semeval/elmo-ful...sent_encoder._text_field_embedder.token_embedd...elmo-full (base)...0.0069731.0685831.499896240Relations0RelationsH(s) = 1.58 bitsK(s) = 0.01
\n", - "

200 rows × 21 columns

\n", - "
" - ], - "text/plain": [ - " tag exp_name exp_type \\\n", - "0 base elmo-full-edges-coref-ontonotes-conll elmo-full \n", - "1 base elmo-full-edges-dep-labeling-ewt elmo-full \n", - "2 base elmo-full-edges-ner-ontonotes elmo-full \n", - "3 base elmo-full-edges-nonterminal-ontonotes elmo-full \n", - "4 base elmo-full-edges-pos-ontonotes elmo-full \n", - "5 base elmo-full-edges-spr1 elmo-full \n", - "6 base elmo-full-edges-srl-conll2012 elmo-full \n", - "7 base elmo-full-edges-rel-semeval elmo-full \n", - "8 base elmo-full-edges-coref-ontonotes-conll elmo-full \n", - "9 base elmo-full-edges-dep-labeling-ewt elmo-full \n", - "10 base elmo-full-edges-ner-ontonotes elmo-full \n", - "11 base elmo-full-edges-nonterminal-ontonotes elmo-full \n", - "12 base elmo-full-edges-pos-ontonotes elmo-full \n", - "13 base elmo-full-edges-spr1 elmo-full \n", - "14 base elmo-full-edges-srl-conll2012 elmo-full \n", - "15 base elmo-full-edges-rel-semeval elmo-full \n", - "16 base elmo-full-edges-coref-ontonotes-conll elmo-full \n", - "17 base elmo-full-edges-dep-labeling-ewt elmo-full \n", - "18 base elmo-full-edges-ner-ontonotes elmo-full \n", - "19 base elmo-full-edges-nonterminal-ontonotes elmo-full \n", - "20 base elmo-full-edges-pos-ontonotes elmo-full \n", - "21 base elmo-full-edges-spr1 elmo-full \n", - "22 base elmo-full-edges-srl-conll2012 elmo-full \n", - "23 base elmo-full-edges-rel-semeval elmo-full \n", - "24 base elmo-full-edges-coref-ontonotes-conll elmo-full \n", - "25 base elmo-full-edges-dep-labeling-ewt elmo-full \n", - "26 base elmo-full-edges-ner-ontonotes elmo-full \n", - "27 base elmo-full-edges-nonterminal-ontonotes elmo-full \n", - "28 base elmo-full-edges-pos-ontonotes elmo-full \n", - "29 base elmo-full-edges-spr1 elmo-full \n", - ".. ... ... ... \n", - "170 base elmo-full-edges-ner-ontonotes elmo-full \n", - "171 base elmo-full-edges-nonterminal-ontonotes elmo-full \n", - "172 base elmo-full-edges-pos-ontonotes elmo-full \n", - "173 base elmo-full-edges-spr1 elmo-full \n", - "174 base elmo-full-edges-srl-conll2012 elmo-full \n", - "175 base elmo-full-edges-rel-semeval elmo-full \n", - "176 base elmo-full-edges-coref-ontonotes-conll elmo-full \n", - "177 base elmo-full-edges-dep-labeling-ewt elmo-full \n", - "178 base elmo-full-edges-ner-ontonotes elmo-full \n", - "179 base elmo-full-edges-nonterminal-ontonotes elmo-full \n", - "180 base elmo-full-edges-pos-ontonotes elmo-full \n", - "181 base elmo-full-edges-spr1 elmo-full \n", - "182 base elmo-full-edges-srl-conll2012 elmo-full \n", - "183 base elmo-full-edges-rel-semeval elmo-full \n", - "184 base elmo-full-edges-coref-ontonotes-conll elmo-full \n", - "185 base elmo-full-edges-dep-labeling-ewt elmo-full \n", - "186 base elmo-full-edges-ner-ontonotes elmo-full \n", - "187 base elmo-full-edges-nonterminal-ontonotes elmo-full \n", - "188 base elmo-full-edges-pos-ontonotes elmo-full \n", - "189 base elmo-full-edges-spr1 elmo-full \n", - "190 base elmo-full-edges-srl-conll2012 elmo-full \n", - "191 base elmo-full-edges-rel-semeval elmo-full \n", - "192 base elmo-full-edges-coref-ontonotes-conll elmo-full \n", - "193 base elmo-full-edges-dep-labeling-ewt elmo-full \n", - "194 base elmo-full-edges-ner-ontonotes elmo-full \n", - "195 base elmo-full-edges-nonterminal-ontonotes elmo-full \n", - "196 base elmo-full-edges-pos-ontonotes elmo-full \n", - "197 base elmo-full-edges-spr1 elmo-full \n", - "198 base elmo-full-edges-srl-conll2012 elmo-full \n", - "199 base elmo-full-edges-rel-semeval elmo-full \n", - "\n", - " task checkpoint gamma label \\\n", - "0 coref-ontonotes-conll /model_state_eval_best.th 2.094788 None \n", - "1 dep-labeling-ewt /model_state_eval_best.th 3.233000 None \n", - "2 ner-ontonotes /model_state_eval_best.th 2.308605 None \n", - "3 nonterminal-ontonotes /model_state_eval_best.th 2.295377 None \n", - "4 pos-ontonotes /model_state_eval_best.th 0.768965 None \n", - "5 spr1 /model_state_eval_best.th 1.035713 None \n", - "6 srl-conll2012 /model_state_eval_best.th 2.064842 None \n", - "7 rel-semeval /model_state_eval_best.th 1.068652 None \n", - "8 coref-ontonotes-conll /model_state_eval_best.th 2.094788 None \n", - "9 dep-labeling-ewt /model_state_eval_best.th 3.233000 None \n", - "10 ner-ontonotes /model_state_eval_best.th 2.308605 None \n", - "11 nonterminal-ontonotes /model_state_eval_best.th 2.295377 None \n", - "12 pos-ontonotes /model_state_eval_best.th 0.768965 None \n", - "13 spr1 /model_state_eval_best.th 1.035713 None \n", - "14 srl-conll2012 /model_state_eval_best.th 2.064842 None \n", - "15 rel-semeval /model_state_eval_best.th 1.068652 None \n", - "16 coref-ontonotes-conll /model_state_eval_best.th 2.094788 None \n", - "17 dep-labeling-ewt /model_state_eval_best.th 3.233000 None \n", - "18 ner-ontonotes /model_state_eval_best.th 2.308605 None \n", - "19 nonterminal-ontonotes /model_state_eval_best.th 2.295377 None \n", - "20 pos-ontonotes /model_state_eval_best.th 0.768965 None \n", - "21 spr1 /model_state_eval_best.th 1.035713 None \n", - "22 srl-conll2012 /model_state_eval_best.th 2.064842 None \n", - "23 rel-semeval /model_state_eval_best.th 1.068652 None \n", - "24 coref-ontonotes-conll /model_state_eval_best.th 2.094788 None \n", - "25 dep-labeling-ewt /model_state_eval_best.th 3.233000 None \n", - "26 ner-ontonotes /model_state_eval_best.th 2.308605 None \n", - "27 nonterminal-ontonotes /model_state_eval_best.th 2.295377 None \n", - "28 pos-ontonotes /model_state_eval_best.th 0.768965 None \n", - "29 spr1 /model_state_eval_best.th 1.035713 None \n", - ".. ... ... ... ... \n", - "170 ner-ontonotes /model_state_eval_best.th 2.308605 None \n", - "171 nonterminal-ontonotes /model_state_eval_best.th 2.295377 None \n", - "172 pos-ontonotes /model_state_eval_best.th 0.768965 None \n", - "173 spr1 /model_state_eval_best.th 1.035713 None \n", - "174 srl-conll2012 /model_state_eval_best.th 2.064842 None \n", - "175 rel-semeval /model_state_eval_best.th 1.068652 None \n", - "176 coref-ontonotes-conll /model_state_eval_best.th 2.094788 None \n", - "177 dep-labeling-ewt /model_state_eval_best.th 3.233000 None \n", - "178 ner-ontonotes /model_state_eval_best.th 2.308605 None \n", - "179 nonterminal-ontonotes /model_state_eval_best.th 2.295377 None \n", - "180 pos-ontonotes /model_state_eval_best.th 0.768965 None \n", - "181 spr1 /model_state_eval_best.th 1.035713 None \n", - "182 srl-conll2012 /model_state_eval_best.th 2.064842 None \n", - "183 rel-semeval /model_state_eval_best.th 1.068652 None \n", - "184 coref-ontonotes-conll /model_state_eval_best.th 2.094788 None \n", - "185 dep-labeling-ewt /model_state_eval_best.th 3.233000 None \n", - "186 ner-ontonotes /model_state_eval_best.th 2.308605 None \n", - "187 nonterminal-ontonotes /model_state_eval_best.th 2.295377 None \n", - "188 pos-ontonotes /model_state_eval_best.th 0.768965 None \n", - "189 spr1 /model_state_eval_best.th 1.035713 None \n", - "190 srl-conll2012 /model_state_eval_best.th 2.064842 None \n", - "191 rel-semeval /model_state_eval_best.th 1.068652 None \n", - "192 coref-ontonotes-conll /model_state_eval_best.th 2.094788 None \n", - "193 dep-labeling-ewt /model_state_eval_best.th 3.233000 None \n", - "194 ner-ontonotes /model_state_eval_best.th 2.308605 None \n", - "195 nonterminal-ontonotes /model_state_eval_best.th 2.295377 None \n", - "196 pos-ontonotes /model_state_eval_best.th 0.768965 None \n", - "197 spr1 /model_state_eval_best.th 1.035713 None \n", - "198 srl-conll2012 /model_state_eval_best.th 2.064842 None \n", - "199 rel-semeval /model_state_eval_best.th 1.068652 None \n", - "\n", - " run \\\n", - "0 elmo-full-edges-coref-ontonotes-conll/run \n", - "1 elmo-full-edges-dep-labeling-ewt/run \n", - "2 elmo-full-edges-ner-ontonotes/run \n", - "3 elmo-full-edges-nonterminal-ontonotes/run \n", - "4 elmo-full-edges-pos-ontonotes/run \n", - "5 elmo-full-edges-spr1/run \n", - "6 elmo-full-edges-srl-conll2012/run \n", - "7 /nfs/jsalt/exp/edges-20190205-semeval/elmo-ful... \n", - "8 elmo-full-edges-coref-ontonotes-conll/run \n", - "9 elmo-full-edges-dep-labeling-ewt/run \n", - "10 elmo-full-edges-ner-ontonotes/run \n", - "11 elmo-full-edges-nonterminal-ontonotes/run \n", - "12 elmo-full-edges-pos-ontonotes/run \n", - "13 elmo-full-edges-spr1/run \n", - "14 elmo-full-edges-srl-conll2012/run \n", - "15 /nfs/jsalt/exp/edges-20190205-semeval/elmo-ful... \n", - "16 elmo-full-edges-coref-ontonotes-conll/run \n", - "17 elmo-full-edges-dep-labeling-ewt/run \n", - "18 elmo-full-edges-ner-ontonotes/run \n", - "19 elmo-full-edges-nonterminal-ontonotes/run \n", - "20 elmo-full-edges-pos-ontonotes/run \n", - "21 elmo-full-edges-spr1/run \n", - "22 elmo-full-edges-srl-conll2012/run \n", - "23 /nfs/jsalt/exp/edges-20190205-semeval/elmo-ful... \n", - "24 elmo-full-edges-coref-ontonotes-conll/run \n", - "25 elmo-full-edges-dep-labeling-ewt/run \n", - "26 elmo-full-edges-ner-ontonotes/run \n", - "27 elmo-full-edges-nonterminal-ontonotes/run \n", - "28 elmo-full-edges-pos-ontonotes/run \n", - "29 elmo-full-edges-spr1/run \n", - ".. ... \n", - "170 elmo-full-edges-ner-ontonotes/run \n", - "171 elmo-full-edges-nonterminal-ontonotes/run \n", - "172 elmo-full-edges-pos-ontonotes/run \n", - "173 elmo-full-edges-spr1/run \n", - "174 elmo-full-edges-srl-conll2012/run \n", - "175 /nfs/jsalt/exp/edges-20190205-semeval/elmo-ful... \n", - "176 elmo-full-edges-coref-ontonotes-conll/run \n", - "177 elmo-full-edges-dep-labeling-ewt/run \n", - "178 elmo-full-edges-ner-ontonotes/run \n", - "179 elmo-full-edges-nonterminal-ontonotes/run \n", - "180 elmo-full-edges-pos-ontonotes/run \n", - "181 elmo-full-edges-spr1/run \n", - "182 elmo-full-edges-srl-conll2012/run \n", - "183 /nfs/jsalt/exp/edges-20190205-semeval/elmo-ful... \n", - "184 elmo-full-edges-coref-ontonotes-conll/run \n", - "185 elmo-full-edges-dep-labeling-ewt/run \n", - "186 elmo-full-edges-ner-ontonotes/run \n", - "187 elmo-full-edges-nonterminal-ontonotes/run \n", - "188 elmo-full-edges-pos-ontonotes/run \n", - "189 elmo-full-edges-spr1/run \n", - "190 elmo-full-edges-srl-conll2012/run \n", - "191 /nfs/jsalt/exp/edges-20190205-semeval/elmo-ful... \n", - "192 elmo-full-edges-coref-ontonotes-conll/run \n", - "193 elmo-full-edges-dep-labeling-ewt/run \n", - "194 elmo-full-edges-ner-ontonotes/run \n", - "195 elmo-full-edges-nonterminal-ontonotes/run \n", - "196 elmo-full-edges-pos-ontonotes/run \n", - "197 elmo-full-edges-spr1/run \n", - "198 elmo-full-edges-srl-conll2012/run \n", - "199 /nfs/jsalt/exp/edges-20190205-semeval/elmo-ful... \n", - "\n", - " scalar_set display_col \\\n", - "0 sent_encoder._text_field_embedder.token_embedd... elmo-full (base) \n", - "1 sent_encoder._text_field_embedder.token_embedd... elmo-full (base) \n", - "2 sent_encoder._text_field_embedder.token_embedd... elmo-full (base) \n", - "3 sent_encoder._text_field_embedder.token_embedd... elmo-full (base) \n", - "4 sent_encoder._text_field_embedder.token_embedd... elmo-full (base) \n", - "5 sent_encoder._text_field_embedder.token_embedd... elmo-full (base) \n", - "6 sent_encoder._text_field_embedder.token_embedd... elmo-full (base) \n", - "7 sent_encoder._text_field_embedder.token_embedd... elmo-full (base) \n", - "8 sent_encoder._text_field_embedder.token_embedd... elmo-full (base) \n", - "9 sent_encoder._text_field_embedder.token_embedd... elmo-full (base) \n", - "10 sent_encoder._text_field_embedder.token_embedd... elmo-full (base) \n", - "11 sent_encoder._text_field_embedder.token_embedd... elmo-full (base) \n", - "12 sent_encoder._text_field_embedder.token_embedd... elmo-full (base) \n", - "13 sent_encoder._text_field_embedder.token_embedd... elmo-full (base) \n", - "14 sent_encoder._text_field_embedder.token_embedd... elmo-full (base) \n", - "15 sent_encoder._text_field_embedder.token_embedd... elmo-full (base) \n", - "16 sent_encoder._text_field_embedder.token_embedd... elmo-full (base) \n", - "17 sent_encoder._text_field_embedder.token_embedd... elmo-full (base) \n", - "18 sent_encoder._text_field_embedder.token_embedd... elmo-full (base) \n", - "19 sent_encoder._text_field_embedder.token_embedd... elmo-full (base) \n", - "20 sent_encoder._text_field_embedder.token_embedd... elmo-full (base) \n", - "21 sent_encoder._text_field_embedder.token_embedd... elmo-full (base) \n", - "22 sent_encoder._text_field_embedder.token_embedd... elmo-full (base) \n", - "23 sent_encoder._text_field_embedder.token_embedd... elmo-full (base) \n", - "24 sent_encoder._text_field_embedder.token_embedd... elmo-full (base) \n", - "25 sent_encoder._text_field_embedder.token_embedd... elmo-full (base) \n", - "26 sent_encoder._text_field_embedder.token_embedd... elmo-full (base) \n", - "27 sent_encoder._text_field_embedder.token_embedd... elmo-full (base) \n", - "28 sent_encoder._text_field_embedder.token_embedd... elmo-full (base) \n", - "29 sent_encoder._text_field_embedder.token_embedd... elmo-full (base) \n", - ".. ... ... \n", - "170 sent_encoder._text_field_embedder.token_embedd... elmo-full (base) \n", - "171 sent_encoder._text_field_embedder.token_embedd... elmo-full (base) \n", - "172 sent_encoder._text_field_embedder.token_embedd... elmo-full (base) \n", - "173 sent_encoder._text_field_embedder.token_embedd... elmo-full (base) \n", - "174 sent_encoder._text_field_embedder.token_embedd... elmo-full (base) \n", - "175 sent_encoder._text_field_embedder.token_embedd... elmo-full (base) \n", - "176 sent_encoder._text_field_embedder.token_embedd... elmo-full (base) \n", - "177 sent_encoder._text_field_embedder.token_embedd... elmo-full (base) \n", - "178 sent_encoder._text_field_embedder.token_embedd... elmo-full (base) \n", - "179 sent_encoder._text_field_embedder.token_embedd... elmo-full (base) \n", - "180 sent_encoder._text_field_embedder.token_embedd... elmo-full (base) \n", - "181 sent_encoder._text_field_embedder.token_embedd... elmo-full (base) \n", - "182 sent_encoder._text_field_embedder.token_embedd... elmo-full (base) \n", - "183 sent_encoder._text_field_embedder.token_embedd... elmo-full (base) \n", - "184 sent_encoder._text_field_embedder.token_embedd... elmo-full (base) \n", - "185 sent_encoder._text_field_embedder.token_embedd... elmo-full (base) \n", - "186 sent_encoder._text_field_embedder.token_embedd... elmo-full (base) \n", - "187 sent_encoder._text_field_embedder.token_embedd... elmo-full (base) \n", - "188 sent_encoder._text_field_embedder.token_embedd... elmo-full (base) \n", - "189 sent_encoder._text_field_embedder.token_embedd... elmo-full (base) \n", - "190 sent_encoder._text_field_embedder.token_embedd... elmo-full (base) \n", - "191 sent_encoder._text_field_embedder.token_embedd... elmo-full (base) \n", - "192 sent_encoder._text_field_embedder.token_embedd... elmo-full (base) \n", - "193 sent_encoder._text_field_embedder.token_embedd... elmo-full (base) \n", - "194 sent_encoder._text_field_embedder.token_embedd... elmo-full (base) \n", - "195 sent_encoder._text_field_embedder.token_embedd... elmo-full (base) \n", - "196 sent_encoder._text_field_embedder.token_embedd... elmo-full (base) \n", - "197 sent_encoder._text_field_embedder.token_embedd... elmo-full (base) \n", - "198 sent_encoder._text_field_embedder.token_embedd... elmo-full (base) \n", - "199 sent_encoder._text_field_embedder.token_embedd... elmo-full (base) \n", - "\n", - " ... weight_kl_unif weight_exp_layer \\\n", - "0 ... 0.099761 0.873651 \n", - "1 ... 0.821292 1.001022 \n", - "2 ... 0.035871 0.966025 \n", - "3 ... 0.770121 0.996855 \n", - "4 ... 0.137134 0.807429 \n", - "5 ... 0.003384 1.018538 \n", - "6 ... 0.475175 0.968179 \n", - "7 ... 0.006973 1.068583 \n", - "8 ... 0.099761 0.873651 \n", - "9 ... 0.821292 1.001022 \n", - "10 ... 0.035871 0.966025 \n", - "11 ... 0.770121 0.996855 \n", - "12 ... 0.137134 0.807429 \n", - "13 ... 0.003384 1.018538 \n", - "14 ... 0.475175 0.968179 \n", - "15 ... 0.006973 1.068583 \n", - "16 ... 0.099761 0.873651 \n", - "17 ... 0.821292 1.001022 \n", - "18 ... 0.035871 0.966025 \n", - "19 ... 0.770121 0.996855 \n", - "20 ... 0.137134 0.807429 \n", - "21 ... 0.003384 1.018538 \n", - "22 ... 0.475175 0.968179 \n", - "23 ... 0.006973 1.068583 \n", - "24 ... 0.099761 0.873651 \n", - "25 ... 0.821292 1.001022 \n", - "26 ... 0.035871 0.966025 \n", - "27 ... 0.770121 0.996855 \n", - "28 ... 0.137134 0.807429 \n", - "29 ... 0.003384 1.018538 \n", - ".. ... ... ... \n", - "170 ... 0.035871 0.966025 \n", - "171 ... 0.770121 0.996855 \n", - "172 ... 0.137134 0.807429 \n", - "173 ... 0.003384 1.018538 \n", - "174 ... 0.475175 0.968179 \n", - "175 ... 0.006973 1.068583 \n", - "176 ... 0.099761 0.873651 \n", - "177 ... 0.821292 1.001022 \n", - "178 ... 0.035871 0.966025 \n", - "179 ... 0.770121 0.996855 \n", - "180 ... 0.137134 0.807429 \n", - "181 ... 0.003384 1.018538 \n", - "182 ... 0.475175 0.968179 \n", - "183 ... 0.006973 1.068583 \n", - "184 ... 0.099761 0.873651 \n", - "185 ... 0.821292 1.001022 \n", - "186 ... 0.035871 0.966025 \n", - "187 ... 0.770121 0.996855 \n", - "188 ... 0.137134 0.807429 \n", - "189 ... 0.003384 1.018538 \n", - "190 ... 0.475175 0.968179 \n", - "191 ... 0.006973 1.068583 \n", - "192 ... 0.099761 0.873651 \n", - "193 ... 0.821292 1.001022 \n", - "194 ... 0.035871 0.966025 \n", - "195 ... 0.770121 0.996855 \n", - "196 ... 0.137134 0.807429 \n", - "197 ... 0.003384 1.018538 \n", - "198 ... 0.475175 0.968179 \n", - "199 ... 0.006973 1.068583 \n", - "\n", - " weight_exp_layer_oneplus layer_num layer_weight _display_name \\\n", - "0 1.279741 0 0.317322 Coref. \n", - "1 1.082230 0 0.0750376 Deps. \n", - "2 1.375614 0 0.29775 Entities \n", - "3 1.089024 0 0.0846346 Consts. \n", - "4 1.237478 0 0.347521 POS \n", - "5 1.473512 0 0.308769 SPR \n", - "6 1.140540 0 0.151122 SRL \n", - "7 1.499896 0 0.287562 Relations \n", - "8 1.279741 1 0.491705 Coref. \n", - "9 1.082230 1 0.848903 Deps. \n", - "10 1.375614 1 0.438475 Entities \n", - "11 1.089024 1 0.833876 Consts. \n", - "12 1.237478 1 0.49753 POS \n", - "13 1.473512 1 0.363925 SPR \n", - "14 1.140540 1 0.729577 SRL \n", - "15 1.499896 1 0.356293 Relations \n", - "16 1.279741 2 0.190973 Coref. \n", - "17 1.082230 2 0.0760595 Deps. \n", - "18 1.375614 2 0.263775 Entities \n", - "19 1.089024 2 0.0814892 Consts. \n", - "20 1.237478 2 0.154949 POS \n", - "21 1.473512 2 0.327306 SPR \n", - "22 1.140540 2 0.119301 SRL \n", - "23 1.499896 2 0.356145 Relations \n", - "24 1.279741 3 0 Coref. \n", - "25 1.082230 3 0 Deps. \n", - "26 1.375614 3 0 Entities \n", - "27 1.089024 3 0 Consts. \n", - "28 1.237478 3 0 POS \n", - "29 1.473512 3 0 SPR \n", - ".. ... ... ... ... \n", - "170 1.375614 21 0 Entities \n", - "171 1.089024 21 0 Consts. \n", - "172 1.237478 21 0 POS \n", - "173 1.473512 21 0 SPR \n", - "174 1.140540 21 0 SRL \n", - "175 1.499896 21 0 Relations \n", - "176 1.279741 22 0 Coref. \n", - "177 1.082230 22 0 Deps. \n", - "178 1.375614 22 0 Entities \n", - "179 1.089024 22 0 Consts. \n", - "180 1.237478 22 0 POS \n", - "181 1.473512 22 0 SPR \n", - "182 1.140540 22 0 SRL \n", - "183 1.499896 22 0 Relations \n", - "184 1.279741 23 0 Coref. \n", - "185 1.082230 23 0 Deps. \n", - "186 1.375614 23 0 Entities \n", - "187 1.089024 23 0 Consts. \n", - "188 1.237478 23 0 POS \n", - "189 1.473512 23 0 SPR \n", - "190 1.140540 23 0 SRL \n", - "191 1.499896 23 0 Relations \n", - "192 1.279741 24 0 Coref. \n", - "193 1.082230 24 0 Deps. \n", - "194 1.375614 24 0 Entities \n", - "195 1.089024 24 0 Consts. \n", - "196 1.237478 24 0 POS \n", - "197 1.473512 24 0 SPR \n", - "198 1.140540 24 0 SRL \n", - "199 1.499896 24 0 Relations \n", - "\n", - " _bar_height _bar_center _formatted_entropy _formatted_kl_unif \n", - "0 0.666376 Coref. H(s) = 1.49 bits K(s) = 0.10 \n", - "1 0.157579 Deps. H(s) = 0.76 bits K(s) = 0.82 \n", - "2 0.625275 Entities H(s) = 1.55 bits K(s) = 0.04 \n", - "3 0.177733 Consts. H(s) = 0.81 bits K(s) = 0.77 \n", - "4 0.729793 POS H(s) = 1.45 bits K(s) = 0.14 \n", - "5 0.648414 SPR H(s) = 1.58 bits K(s) = 0.00 \n", - "6 0.317356 SRL H(s) = 1.11 bits K(s) = 0.48 \n", - "7 0.60388 Relations H(s) = 1.58 bits K(s) = 0.01 \n", - "8 1.03258 Coref. H(s) = 1.49 bits K(s) = 0.10 \n", - "9 1.7827 Deps. H(s) = 0.76 bits K(s) = 0.82 \n", - "10 0.920797 Entities H(s) = 1.55 bits K(s) = 0.04 \n", - "11 1.75114 Consts. H(s) = 0.81 bits K(s) = 0.77 \n", - "12 1.04481 POS H(s) = 1.45 bits K(s) = 0.14 \n", - "13 0.764243 SPR H(s) = 1.58 bits K(s) = 0.00 \n", - "14 1.53211 SRL H(s) = 1.11 bits K(s) = 0.48 \n", - "15 0.748216 Relations H(s) = 1.58 bits K(s) = 0.01 \n", - "16 0.401043 Coref. H(s) = 1.49 bits K(s) = 0.10 \n", - "17 0.159725 Deps. H(s) = 0.76 bits K(s) = 0.82 \n", - "18 0.553928 Entities H(s) = 1.55 bits K(s) = 0.04 \n", - "19 0.171127 Consts. H(s) = 0.81 bits K(s) = 0.77 \n", - "20 0.325394 POS H(s) = 1.45 bits K(s) = 0.14 \n", - "21 0.687343 SPR H(s) = 1.58 bits K(s) = 0.00 \n", - "22 0.250532 SRL H(s) = 1.11 bits K(s) = 0.48 \n", - "23 0.747904 Relations H(s) = 1.58 bits K(s) = 0.01 \n", - "24 0 Coref. H(s) = 1.49 bits K(s) = 0.10 \n", - "25 0 Deps. H(s) = 0.76 bits K(s) = 0.82 \n", - "26 0 Entities H(s) = 1.55 bits K(s) = 0.04 \n", - "27 0 Consts. H(s) = 0.81 bits K(s) = 0.77 \n", - "28 0 POS H(s) = 1.45 bits K(s) = 0.14 \n", - "29 0 SPR H(s) = 1.58 bits K(s) = 0.00 \n", - ".. ... ... ... ... \n", - "170 0 Entities H(s) = 1.55 bits K(s) = 0.04 \n", - "171 0 Consts. H(s) = 0.81 bits K(s) = 0.77 \n", - "172 0 POS H(s) = 1.45 bits K(s) = 0.14 \n", - "173 0 SPR H(s) = 1.58 bits K(s) = 0.00 \n", - "174 0 SRL H(s) = 1.11 bits K(s) = 0.48 \n", - "175 0 Relations H(s) = 1.58 bits K(s) = 0.01 \n", - "176 0 Coref. H(s) = 1.49 bits K(s) = 0.10 \n", - "177 0 Deps. H(s) = 0.76 bits K(s) = 0.82 \n", - "178 0 Entities H(s) = 1.55 bits K(s) = 0.04 \n", - "179 0 Consts. H(s) = 0.81 bits K(s) = 0.77 \n", - "180 0 POS H(s) = 1.45 bits K(s) = 0.14 \n", - "181 0 SPR H(s) = 1.58 bits K(s) = 0.00 \n", - "182 0 SRL H(s) = 1.11 bits K(s) = 0.48 \n", - "183 0 Relations H(s) = 1.58 bits K(s) = 0.01 \n", - "184 0 Coref. H(s) = 1.49 bits K(s) = 0.10 \n", - "185 0 Deps. H(s) = 0.76 bits K(s) = 0.82 \n", - "186 0 Entities H(s) = 1.55 bits K(s) = 0.04 \n", - "187 0 Consts. H(s) = 0.81 bits K(s) = 0.77 \n", - "188 0 POS H(s) = 1.45 bits K(s) = 0.14 \n", - "189 0 SPR H(s) = 1.58 bits K(s) = 0.00 \n", - "190 0 SRL H(s) = 1.11 bits K(s) = 0.48 \n", - "191 0 Relations H(s) = 1.58 bits K(s) = 0.01 \n", - "192 0 Coref. H(s) = 1.49 bits K(s) = 0.10 \n", - "193 0 Deps. H(s) = 0.76 bits K(s) = 0.82 \n", - "194 0 Entities H(s) = 1.55 bits K(s) = 0.04 \n", - "195 0 Consts. H(s) = 0.81 bits K(s) = 0.77 \n", - "196 0 POS H(s) = 1.45 bits K(s) = 0.14 \n", - "197 0 SPR H(s) = 1.58 bits K(s) = 0.00 \n", - "198 0 SRL H(s) = 1.11 bits K(s) = 0.48 \n", - "199 0 Relations H(s) = 1.58 bits K(s) = 0.01 \n", - "\n", - "[200 rows x 21 columns]" - ] - }, - "execution_count": 43, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "weight_df" - ] - }, - { - "cell_type": "code", - "execution_count": 44, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,\n", - " 19, 20, 21, 22, 23, 24], dtype=object)" - ] - }, - "execution_count": 44, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "weight_df.layer_num.unique()" - ] - }, - { - "cell_type": "code", - "execution_count": 49, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/usr/share/anaconda3/lib/python3.6/site-packages/bokeh/plotting/helpers.py:591: UserWarning: HoverTool are being repeated\n", - " warnings.warn(\"%s are being repeated\" % \",\".join(repeated_tools))\n" - ] - }, - { - "data": { - "text/html": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": [ - "(function(root) {\n", - " function embed_document(root) {\n", - " \n", - " var docs_json = {\"91e6a285-ac1b-48da-afcd-150f6ad88247\":{\"roots\":{\"references\":[{\"attributes\":{\"below\":[{\"id\":\"7223\",\"type\":\"LinearAxis\"}],\"left\":[{\"id\":\"7228\",\"type\":\"CategoricalAxis\"}],\"min_border_bottom\":0,\"min_border_left\":0,\"min_border_right\":0,\"min_border_top\":0,\"plot_height\":750,\"plot_width\":200,\"renderers\":[{\"id\":\"7223\",\"type\":\"LinearAxis\"},{\"id\":\"7227\",\"type\":\"Grid\"},{\"id\":\"7228\",\"type\":\"CategoricalAxis\"},{\"id\":\"7231\",\"type\":\"Grid\"},{\"id\":\"7241\",\"type\":\"GlyphRenderer\"},{\"id\":\"7247\",\"type\":\"GlyphRenderer\"},{\"id\":\"7255\",\"type\":\"GlyphRenderer\"},{\"id\":\"7261\",\"type\":\"GlyphRenderer\"},{\"id\":\"7269\",\"type\":\"GlyphRenderer\"},{\"id\":\"7275\",\"type\":\"GlyphRenderer\"},{\"id\":\"7280\",\"type\":\"LabelSet\"},{\"id\":\"7283\",\"type\":\"LabelSet\"}],\"title\":{\"id\":\"7574\",\"type\":\"Title\"},\"toolbar\":{\"id\":\"7233\",\"type\":\"Toolbar\"},\"toolbar_location\":null,\"x_range\":{\"id\":\"7216\",\"type\":\"Range1d\"},\"x_scale\":{\"id\":\"7219\",\"type\":\"LinearScale\"},\"y_range\":{\"id\":\"7214\",\"type\":\"FactorRange\"},\"y_scale\":{\"id\":\"7221\",\"type\":\"CategoricalScale\"}},\"id\":\"7215\",\"subtype\":\"Figure\",\"type\":\"Plot\"},{\"attributes\":{},\"id\":\"7582\",\"type\":\"Selection\"},{\"attributes\":{\"active_drag\":\"auto\",\"active_inspect\":\"auto\",\"active_multi\":null,\"active_scroll\":\"auto\",\"active_tap\":\"auto\",\"tools\":[{\"id\":\"7212\",\"type\":\"HoverTool\"},{\"id\":\"7213\",\"type\":\"HoverTool\"},{\"id\":\"7232\",\"type\":\"SaveTool\"}]},\"id\":\"7233\",\"type\":\"Toolbar\"},{\"attributes\":{},\"id\":\"7593\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"source\":{\"id\":\"7264\",\"type\":\"ColumnDataSource\"}},\"id\":\"7270\",\"type\":\"CDSView\"},{\"attributes\":{\"callback\":null,\"data\":{\"_bar_center\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"_bar_height\":[],\"_display_name\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"_fill_color\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"_formatted_exp_layer\":[],\"_formatted_kl_unif\":[],\"_line_color\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"accuracy\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"accuracy_errn95\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"contextual_headroom\":[],\"delta_score\":[],\"display_col\":[],\"display_row\":[],\"exp_layer\":[],\"exp_name\":[],\"exp_type\":[],\"f1_errn95\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"f1_score\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"fn_count\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"fp_count\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"headroom_frac\":[],\"index\":[],\"kl_unif\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"label\":[],\"layer_num\":[],\"lex_score\":[],\"max_layer_score\":[],\"num_epochs\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"num_steps\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"precision\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"precision_errn95\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"pred_pos_count\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"prev_layer_score\":[],\"prev_score_max\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"real_delta_score\":[],\"real_headroom_frac\":[],\"recall\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"recall_errn95\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"run\":[],\"score\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"score_errn95\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"seed\":[],\"split\":[],\"stratifier\":[],\"stratum_key\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"tag\":[],\"task\":[],\"tn_count\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"total_count\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"tp_count\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"true_pos_count\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]}},\"selected\":{\"id\":\"7588\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"7589\",\"type\":\"UnionRenderers\"}},\"id\":\"7271\",\"type\":\"ColumnDataSource\"},{\"attributes\":{},\"id\":\"7219\",\"type\":\"LinearScale\"},{\"attributes\":{\"callback\":null,\"factor_padding\":0.1,\"factors\":[\"Relations\",\"SPR\",\"Coref.\",\"SRL\",\"Entities\",\"Deps.\",\"Consts.\",\"POS\"]},\"id\":\"7214\",\"type\":\"FactorRange\"},{\"attributes\":{\"callback\":null,\"data\":{\"_bar_center\":[\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\"],\"_bar_height\":[0.31732210516929626,0.07503759860992432,0.2977501153945923,0.08463462442159653,0.3475206792354584,0.3087686002254486,0.15112213790416718,0.2875621020793915,0.4917048215866089,0.8489028811454773,0.4384748637676239,0.8338761925697327,0.49752989411354065,0.36392515897750854,0.7295767664909363,0.3562931716442108,0.19097307324409485,0.0760594829916954,0.2637750506401062,0.0814892128109932,0.15494942665100098,0.32730621099472046,0.11930105835199356,0.3561447262763977,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0],\"_display_name\":[\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\"],\"_formatted_entropy\":[\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\"],\"_formatted_kl_unif\":[\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\"],\"checkpoint\":[\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\"],\"display_col\":[\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\"],\"exp_name\":[\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\"],\"exp_type\":[\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\"],\"gamma\":{\"__ndarray__\":\"AAAAICDCAED/////Lt0JQAAAAMAFeAJAAAAA4O5cAkAAAADAW5voPwAAAABIkvA/AAAAoMuEAEAAAAAAMxnxPwAAACAgwgBA/////y7dCUAAAADABXgCQAAAAODuXAJAAAAAwFub6D8AAAAASJLwPwAAAKDLhABAAAAAADMZ8T8AAAAgIMIAQP////8u3QlAAAAAwAV4AkAAAADg7lwCQAAAAMBbm+g/AAAAAEiS8D8AAACgy4QAQAAAAAAzGfE/AAAAICDCAED/////Lt0JQAAAAMAFeAJAAAAA4O5cAkAAAADAW5voPwAAAABIkvA/AAAAoMuEAEAAAAAAMxnxPwAAACAgwgBA/////y7dCUAAAADABXgCQAAAAODuXAJAAAAAwFub6D8AAAAASJLwPwAAAKDLhABAAAAAADMZ8T8AAAAgIMIAQP////8u3QlAAAAAwAV4AkAAAADg7lwCQAAAAMBbm+g/AAAAAEiS8D8AAACgy4QAQAAAAAAzGfE/AAAAICDCAED/////Lt0JQAAAAMAFeAJAAAAA4O5cAkAAAADAW5voPwAAAABIkvA/AAAAoMuEAEAAAAAAMxnxPwAAACAgwgBA/////y7dCUAAAADABXgCQAAAAODuXAJAAAAAwFub6D8AAAAASJLwPwAAAKDLhABAAAAAADMZ8T8AAAAgIMIAQP////8u3QlAAAAAwAV4AkAAAADg7lwCQAAAAMBbm+g/AAAAAEiS8D8AAACgy4QAQAAAAAAzGfE/AAAAICDCAED/////Lt0JQAAAAMAFeAJAAAAA4O5cAkAAAADAW5voPwAAAABIkvA/AAAAoMuEAEAAAAAAMxnxPwAAACAgwgBA/////y7dCUAAAADABXgCQAAAAODuXAJAAAAAwFub6D8AAAAASJLwPwAAAKDLhABAAAAAADMZ8T8AAAAgIMIAQP////8u3QlAAAAAwAV4AkAAAADg7lwCQAAAAMBbm+g/AAAAAEiS8D8AAACgy4QAQAAAAAAzGfE/AAAAICDCAED/////Lt0JQAAAAMAFeAJAAAAA4O5cAkAAAADAW5voPwAAAABIkvA/AAAAoMuEAEAAAAAAMxnxPwAAACAgwgBA/////y7dCUAAAADABXgCQAAAAODuXAJAAAAAwFub6D8AAAAASJLwPwAAAKDLhABAAAAAADMZ8T8AAAAgIMIAQP////8u3QlAAAAAwAV4AkAAAADg7lwCQAAAAMBbm+g/AAAAAEiS8D8AAACgy4QAQAAAAAAzGfE/AAAAICDCAED/////Lt0JQAAAAMAFeAJAAAAA4O5cAkAAAADAW5voPwAAAABIkvA/AAAAoMuEAEAAAAAAMxnxPwAAACAgwgBA/////y7dCUAAAADABXgCQAAAAODuXAJAAAAAwFub6D8AAAAASJLwPwAAAKDLhABAAAAAADMZ8T8AAAAgIMIAQP////8u3QlAAAAAwAV4AkAAAADg7lwCQAAAAMBbm+g/AAAAAEiS8D8AAACgy4QAQAAAAAAzGfE/AAAAICDCAED/////Lt0JQAAAAMAFeAJAAAAA4O5cAkAAAADAW5voPwAAAABIkvA/AAAAoMuEAEAAAAAAMxnxPwAAACAgwgBA/////y7dCUAAAADABXgCQAAAAODuXAJAAAAAwFub6D8AAAAASJLwPwAAAKDLhABAAAAAADMZ8T8AAAAgIMIAQP////8u3QlAAAAAwAV4AkAAAADg7lwCQAAAAMBbm+g/AAAAAEiS8D8AAACgy4QAQAAAAAAzGfE/AAAAICDCAED/////Lt0JQAAAAMAFeAJAAAAA4O5cAkAAAADAW5voPwAAAABIkvA/AAAAoMuEAEAAAAAAMxnxPwAAACAgwgBA/////y7dCUAAAADABXgCQAAAAODuXAJAAAAAwFub6D8AAAAASJLwPwAAAKDLhABAAAAAADMZ8T8AAAAgIMIAQP////8u3QlAAAAAwAV4AkAAAADg7lwCQAAAAMBbm+g/AAAAAEiS8D8AAACgy4QAQAAAAAAzGfE/AAAAICDCAED/////Lt0JQAAAAMAFeAJAAAAA4O5cAkAAAADAW5voPwAAAABIkvA/AAAAoMuEAEAAAAAAMxnxPw==\",\"dtype\":\"float64\",\"shape\":[200]},\"index\":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199],\"label\":[\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\"],\"layer_num\":[0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8,9,9,9,9,9,9,9,9,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,13,13,13,13,13,13,13,13,14,14,14,14,14,14,14,14,15,15,15,15,15,15,15,15,16,16,16,16,16,16,16,16,17,17,17,17,17,17,17,17,18,18,18,18,18,18,18,18,19,19,19,19,19,19,19,19,20,20,20,20,20,20,20,20,21,21,21,21,21,21,21,21,22,22,22,22,22,22,22,22,23,23,23,23,23,23,23,23,24,24,24,24,24,24,24,24],\"layer_weight\":[0.31732210516929626,0.07503759860992432,0.2977501153945923,0.08463462442159653,0.3475206792354584,0.3087686002254486,0.15112213790416718,0.2875621020793915,0.4917048215866089,0.8489028811454773,0.4384748637676239,0.8338761925697327,0.49752989411354065,0.36392515897750854,0.7295767664909363,0.3562931716442108,0.19097307324409485,0.0760594829916954,0.2637750506401062,0.0814892128109932,0.15494942665100098,0.32730621099472046,0.11930105835199356,0.3561447262763977,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0],\"run\":[\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\"],\"scalar_set\":[\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\"],\"tag\":[\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\"],\"task\":[\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\"],\"weight_entropy\":[1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511],\"weight_exp_layer\":{\"__ndarray__\":\"AAAA4PL06z8AAAB8LwTwPwAAADCt6e4/AAAAqDvm7z8AAADQdNbpPwAAABDuS/A/AAAASFL77j8AAAAY6hjxPwAAAODy9Os/AAAAfC8E8D8AAAAwrenuPwAAAKg75u8/AAAA0HTW6T8AAAAQ7kvwPwAAAEhS++4/AAAAGOoY8T8AAADg8vTrPwAAAHwvBPA/AAAAMK3p7j8AAACoO+bvPwAAANB01uk/AAAAEO5L8D8AAABIUvvuPwAAABjqGPE/AAAA4PL06z8AAAB8LwTwPwAAADCt6e4/AAAAqDvm7z8AAADQdNbpPwAAABDuS/A/AAAASFL77j8AAAAY6hjxPwAAAODy9Os/AAAAfC8E8D8AAAAwrenuPwAAAKg75u8/AAAA0HTW6T8AAAAQ7kvwPwAAAEhS++4/AAAAGOoY8T8AAADg8vTrPwAAAHwvBPA/AAAAMK3p7j8AAACoO+bvPwAAANB01uk/AAAAEO5L8D8AAABIUvvuPwAAABjqGPE/AAAA4PL06z8AAAB8LwTwPwAAADCt6e4/AAAAqDvm7z8AAADQdNbpPwAAABDuS/A/AAAASFL77j8AAAAY6hjxPwAAAODy9Os/AAAAfC8E8D8AAAAwrenuPwAAAKg75u8/AAAA0HTW6T8AAAAQ7kvwPwAAAEhS++4/AAAAGOoY8T8AAADg8vTrPwAAAHwvBPA/AAAAMK3p7j8AAACoO+bvPwAAANB01uk/AAAAEO5L8D8AAABIUvvuPwAAABjqGPE/AAAA4PL06z8AAAB8LwTwPwAAADCt6e4/AAAAqDvm7z8AAADQdNbpPwAAABDuS/A/AAAASFL77j8AAAAY6hjxPwAAAODy9Os/AAAAfC8E8D8AAAAwrenuPwAAAKg75u8/AAAA0HTW6T8AAAAQ7kvwPwAAAEhS++4/AAAAGOoY8T8AAADg8vTrPwAAAHwvBPA/AAAAMK3p7j8AAACoO+bvPwAAANB01uk/AAAAEO5L8D8AAABIUvvuPwAAABjqGPE/AAAA4PL06z8AAAB8LwTwPwAAADCt6e4/AAAAqDvm7z8AAADQdNbpPwAAABDuS/A/AAAASFL77j8AAAAY6hjxPwAAAODy9Os/AAAAfC8E8D8AAAAwrenuPwAAAKg75u8/AAAA0HTW6T8AAAAQ7kvwPwAAAEhS++4/AAAAGOoY8T8AAADg8vTrPwAAAHwvBPA/AAAAMK3p7j8AAACoO+bvPwAAANB01uk/AAAAEO5L8D8AAABIUvvuPwAAABjqGPE/AAAA4PL06z8AAAB8LwTwPwAAADCt6e4/AAAAqDvm7z8AAADQdNbpPwAAABDuS/A/AAAASFL77j8AAAAY6hjxPwAAAODy9Os/AAAAfC8E8D8AAAAwrenuPwAAAKg75u8/AAAA0HTW6T8AAAAQ7kvwPwAAAEhS++4/AAAAGOoY8T8AAADg8vTrPwAAAHwvBPA/AAAAMK3p7j8AAACoO+bvPwAAANB01uk/AAAAEO5L8D8AAABIUvvuPwAAABjqGPE/AAAA4PL06z8AAAB8LwTwPwAAADCt6e4/AAAAqDvm7z8AAADQdNbpPwAAABDuS/A/AAAASFL77j8AAAAY6hjxPwAAAODy9Os/AAAAfC8E8D8AAAAwrenuPwAAAKg75u8/AAAA0HTW6T8AAAAQ7kvwPwAAAEhS++4/AAAAGOoY8T8AAADg8vTrPwAAAHwvBPA/AAAAMK3p7j8AAACoO+bvPwAAANB01uk/AAAAEO5L8D8AAABIUvvuPwAAABjqGPE/AAAA4PL06z8AAAB8LwTwPwAAADCt6e4/AAAAqDvm7z8AAADQdNbpPwAAABDuS/A/AAAASFL77j8AAAAY6hjxPwAAAODy9Os/AAAAfC8E8D8AAAAwrenuPwAAAKg75u8/AAAA0HTW6T8AAAAQ7kvwPwAAAEhS++4/AAAAGOoY8T8AAADg8vTrPwAAAHwvBPA/AAAAMK3p7j8AAACoO+bvPwAAANB01uk/AAAAEO5L8D8AAABIUvvuPwAAABjqGPE/AAAA4PL06z8AAAB8LwTwPwAAADCt6e4/AAAAqDvm7z8AAADQdNbpPwAAABDuS/A/AAAASFL77j8AAAAY6hjxPw==\",\"dtype\":\"float64\",\"shape\":[200]},\"weight_exp_layer_oneplus\":{\"__ndarray__\":\"O9rh39F59D+M1ZY80FDxPzMc3xyEAvY/cfUrH6Rs8T/uGL6ytczzP4UiQhyBk/c/T0HUjaY/8j+oZuXSkv/3Pzva4d/RefQ/jNWWPNBQ8T8zHN8chAL2P3H1Kx+kbPE/7hi+srXM8z+FIkIcgZP3P09B1I2mP/I/qGbl0pL/9z872uHf0Xn0P4zVljzQUPE/MxzfHIQC9j9x9SsfpGzxP+4YvrK1zPM/hSJCHIGT9z9PQdSNpj/yP6hm5dKS//c/O9rh39F59D+M1ZY80FDxPzMc3xyEAvY/cfUrH6Rs8T/uGL6ytczzP4UiQhyBk/c/T0HUjaY/8j+oZuXSkv/3Pzva4d/RefQ/jNWWPNBQ8T8zHN8chAL2P3H1Kx+kbPE/7hi+srXM8z+FIkIcgZP3P09B1I2mP/I/qGbl0pL/9z872uHf0Xn0P4zVljzQUPE/MxzfHIQC9j9x9SsfpGzxP+4YvrK1zPM/hSJCHIGT9z9PQdSNpj/yP6hm5dKS//c/O9rh39F59D+M1ZY80FDxPzMc3xyEAvY/cfUrH6Rs8T/uGL6ytczzP4UiQhyBk/c/T0HUjaY/8j+oZuXSkv/3Pzva4d/RefQ/jNWWPNBQ8T8zHN8chAL2P3H1Kx+kbPE/7hi+srXM8z+FIkIcgZP3P09B1I2mP/I/qGbl0pL/9z872uHf0Xn0P4zVljzQUPE/MxzfHIQC9j9x9SsfpGzxP+4YvrK1zPM/hSJCHIGT9z9PQdSNpj/yP6hm5dKS//c/O9rh39F59D+M1ZY80FDxPzMc3xyEAvY/cfUrH6Rs8T/uGL6ytczzP4UiQhyBk/c/T0HUjaY/8j+oZuXSkv/3Pzva4d/RefQ/jNWWPNBQ8T8zHN8chAL2P3H1Kx+kbPE/7hi+srXM8z+FIkIcgZP3P09B1I2mP/I/qGbl0pL/9z872uHf0Xn0P4zVljzQUPE/MxzfHIQC9j9x9SsfpGzxP+4YvrK1zPM/hSJCHIGT9z9PQdSNpj/yP6hm5dKS//c/O9rh39F59D+M1ZY80FDxPzMc3xyEAvY/cfUrH6Rs8T/uGL6ytczzP4UiQhyBk/c/T0HUjaY/8j+oZuXSkv/3Pzva4d/RefQ/jNWWPNBQ8T8zHN8chAL2P3H1Kx+kbPE/7hi+srXM8z+FIkIcgZP3P09B1I2mP/I/qGbl0pL/9z872uHf0Xn0P4zVljzQUPE/MxzfHIQC9j9x9SsfpGzxP+4YvrK1zPM/hSJCHIGT9z9PQdSNpj/yP6hm5dKS//c/O9rh39F59D+M1ZY80FDxPzMc3xyEAvY/cfUrH6Rs8T/uGL6ytczzP4UiQhyBk/c/T0HUjaY/8j+oZuXSkv/3Pzva4d/RefQ/jNWWPNBQ8T8zHN8chAL2P3H1Kx+kbPE/7hi+srXM8z+FIkIcgZP3P09B1I2mP/I/qGbl0pL/9z872uHf0Xn0P4zVljzQUPE/MxzfHIQC9j9x9SsfpGzxP+4YvrK1zPM/hSJCHIGT9z9PQdSNpj/yP6hm5dKS//c/O9rh39F59D+M1ZY80FDxPzMc3xyEAvY/cfUrH6Rs8T/uGL6ytczzP4UiQhyBk/c/T0HUjaY/8j+oZuXSkv/3Pzva4d/RefQ/jNWWPNBQ8T8zHN8chAL2P3H1Kx+kbPE/7hi+srXM8z+FIkIcgZP3P09B1I2mP/I/qGbl0pL/9z872uHf0Xn0P4zVljzQUPE/MxzfHIQC9j9x9SsfpGzxP+4YvrK1zPM/hSJCHIGT9z9PQdSNpj/yP6hm5dKS//c/O9rh39F59D+M1ZY80FDxPzMc3xyEAvY/cfUrH6Rs8T/uGL6ytczzP4UiQhyBk/c/T0HUjaY/8j+oZuXSkv/3Pzva4d/RefQ/jNWWPNBQ8T8zHN8chAL2P3H1Kx+kbPE/7hi+srXM8z+FIkIcgZP3P09B1I2mP/I/qGbl0pL/9z872uHf0Xn0P4zVljzQUPE/MxzfHIQC9j9x9SsfpGzxP+4YvrK1zPM/hSJCHIGT9z9PQdSNpj/yP6hm5dKS//c/O9rh39F59D+M1ZY80FDxPzMc3xyEAvY/cfUrH6Rs8T/uGL6ytczzP4UiQhyBk/c/T0HUjaY/8j+oZuXSkv/3Pw==\",\"dtype\":\"float64\",\"shape\":[200]},\"weight_kl_unif\":{\"__ndarray__\":\"zYnp3eiJuT+ILOEcBUjqP3rt0nOxXaI/+HX9RtWk6D/tXl6Tmo3BP+8H2W1puWs/Xc9di0Vp3j/ge2yqK5B8P82J6d3oibk/iCzhHAVI6j967dJzsV2iP/h1/UbVpOg/7V5ek5qNwT/vB9ltablrP13PXYtFad4/4HtsqiuQfD/Niend6Im5P4gs4RwFSOo/eu3Sc7Fdoj/4df1G1aToP+1eXpOajcE/7wfZbWm5az9dz12LRWneP+B7bKorkHw/zYnp3eiJuT+ILOEcBUjqP3rt0nOxXaI/+HX9RtWk6D/tXl6Tmo3BP+8H2W1puWs/Xc9di0Vp3j/ge2yqK5B8P82J6d3oibk/iCzhHAVI6j967dJzsV2iP/h1/UbVpOg/7V5ek5qNwT/vB9ltablrP13PXYtFad4/4HtsqiuQfD/Niend6Im5P4gs4RwFSOo/eu3Sc7Fdoj/4df1G1aToP+1eXpOajcE/7wfZbWm5az9dz12LRWneP+B7bKorkHw/zYnp3eiJuT+ILOEcBUjqP3rt0nOxXaI/+HX9RtWk6D/tXl6Tmo3BP+8H2W1puWs/Xc9di0Vp3j/ge2yqK5B8P82J6d3oibk/iCzhHAVI6j967dJzsV2iP/h1/UbVpOg/7V5ek5qNwT/vB9ltablrP13PXYtFad4/4HtsqiuQfD/Niend6Im5P4gs4RwFSOo/eu3Sc7Fdoj/4df1G1aToP+1eXpOajcE/7wfZbWm5az9dz12LRWneP+B7bKorkHw/zYnp3eiJuT+ILOEcBUjqP3rt0nOxXaI/+HX9RtWk6D/tXl6Tmo3BP+8H2W1puWs/Xc9di0Vp3j/ge2yqK5B8P82J6d3oibk/iCzhHAVI6j967dJzsV2iP/h1/UbVpOg/7V5ek5qNwT/vB9ltablrP13PXYtFad4/4HtsqiuQfD/Niend6Im5P4gs4RwFSOo/eu3Sc7Fdoj/4df1G1aToP+1eXpOajcE/7wfZbWm5az9dz12LRWneP+B7bKorkHw/zYnp3eiJuT+ILOEcBUjqP3rt0nOxXaI/+HX9RtWk6D/tXl6Tmo3BP+8H2W1puWs/Xc9di0Vp3j/ge2yqK5B8P82J6d3oibk/iCzhHAVI6j967dJzsV2iP/h1/UbVpOg/7V5ek5qNwT/vB9ltablrP13PXYtFad4/4HtsqiuQfD/Niend6Im5P4gs4RwFSOo/eu3Sc7Fdoj/4df1G1aToP+1eXpOajcE/7wfZbWm5az9dz12LRWneP+B7bKorkHw/zYnp3eiJuT+ILOEcBUjqP3rt0nOxXaI/+HX9RtWk6D/tXl6Tmo3BP+8H2W1puWs/Xc9di0Vp3j/ge2yqK5B8P82J6d3oibk/iCzhHAVI6j967dJzsV2iP/h1/UbVpOg/7V5ek5qNwT/vB9ltablrP13PXYtFad4/4HtsqiuQfD/Niend6Im5P4gs4RwFSOo/eu3Sc7Fdoj/4df1G1aToP+1eXpOajcE/7wfZbWm5az9dz12LRWneP+B7bKorkHw/zYnp3eiJuT+ILOEcBUjqP3rt0nOxXaI/+HX9RtWk6D/tXl6Tmo3BP+8H2W1puWs/Xc9di0Vp3j/ge2yqK5B8P82J6d3oibk/iCzhHAVI6j967dJzsV2iP/h1/UbVpOg/7V5ek5qNwT/vB9ltablrP13PXYtFad4/4HtsqiuQfD/Niend6Im5P4gs4RwFSOo/eu3Sc7Fdoj/4df1G1aToP+1eXpOajcE/7wfZbWm5az9dz12LRWneP+B7bKorkHw/zYnp3eiJuT+ILOEcBUjqP3rt0nOxXaI/+HX9RtWk6D/tXl6Tmo3BP+8H2W1puWs/Xc9di0Vp3j/ge2yqK5B8P82J6d3oibk/iCzhHAVI6j967dJzsV2iP/h1/UbVpOg/7V5ek5qNwT/vB9ltablrP13PXYtFad4/4HtsqiuQfD/Niend6Im5P4gs4RwFSOo/eu3Sc7Fdoj/4df1G1aToP+1eXpOajcE/7wfZbWm5az9dz12LRWneP+B7bKorkHw/zYnp3eiJuT+ILOEcBUjqP3rt0nOxXaI/+HX9RtWk6D/tXl6Tmo3BP+8H2W1puWs/Xc9di0Vp3j/ge2yqK5B8Pw==\",\"dtype\":\"float64\",\"shape\":[200]}},\"selected\":{\"id\":\"7578\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"7579\",\"type\":\"UnionRenderers\"}},\"id\":\"7237\",\"type\":\"ColumnDataSource\"},{\"attributes\":{},\"id\":\"7589\",\"type\":\"UnionRenderers\"},{\"attributes\":{},\"id\":\"7221\",\"type\":\"CategoricalScale\"},{\"attributes\":{\"callback\":null,\"data\":{\"_bar_center\":[\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\"],\"_bar_height\":[0.31732210516929626,0.07503759860992432,0.2977501153945923,0.08463462442159653,0.3475206792354584,0.3087686002254486,0.15112213790416718,0.2875621020793915,0.4917048215866089,0.8489028811454773,0.4384748637676239,0.8338761925697327,0.49752989411354065,0.36392515897750854,0.7295767664909363,0.3562931716442108,0.19097307324409485,0.0760594829916954,0.2637750506401062,0.0814892128109932,0.15494942665100098,0.32730621099472046,0.11930105835199356,0.3561447262763977,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0],\"_display_name\":[\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\"],\"_formatted_entropy\":[\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\"],\"_formatted_kl_unif\":[\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\"],\"checkpoint\":[\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\"],\"display_col\":[\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\"],\"exp_name\":[\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\"],\"exp_type\":[\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\"],\"gamma\":{\"__ndarray__\":\"AAAAICDCAED/////Lt0JQAAAAMAFeAJAAAAA4O5cAkAAAADAW5voPwAAAABIkvA/AAAAoMuEAEAAAAAAMxnxPwAAACAgwgBA/////y7dCUAAAADABXgCQAAAAODuXAJAAAAAwFub6D8AAAAASJLwPwAAAKDLhABAAAAAADMZ8T8AAAAgIMIAQP////8u3QlAAAAAwAV4AkAAAADg7lwCQAAAAMBbm+g/AAAAAEiS8D8AAACgy4QAQAAAAAAzGfE/AAAAICDCAED/////Lt0JQAAAAMAFeAJAAAAA4O5cAkAAAADAW5voPwAAAABIkvA/AAAAoMuEAEAAAAAAMxnxPwAAACAgwgBA/////y7dCUAAAADABXgCQAAAAODuXAJAAAAAwFub6D8AAAAASJLwPwAAAKDLhABAAAAAADMZ8T8AAAAgIMIAQP////8u3QlAAAAAwAV4AkAAAADg7lwCQAAAAMBbm+g/AAAAAEiS8D8AAACgy4QAQAAAAAAzGfE/AAAAICDCAED/////Lt0JQAAAAMAFeAJAAAAA4O5cAkAAAADAW5voPwAAAABIkvA/AAAAoMuEAEAAAAAAMxnxPwAAACAgwgBA/////y7dCUAAAADABXgCQAAAAODuXAJAAAAAwFub6D8AAAAASJLwPwAAAKDLhABAAAAAADMZ8T8AAAAgIMIAQP////8u3QlAAAAAwAV4AkAAAADg7lwCQAAAAMBbm+g/AAAAAEiS8D8AAACgy4QAQAAAAAAzGfE/AAAAICDCAED/////Lt0JQAAAAMAFeAJAAAAA4O5cAkAAAADAW5voPwAAAABIkvA/AAAAoMuEAEAAAAAAMxnxPwAAACAgwgBA/////y7dCUAAAADABXgCQAAAAODuXAJAAAAAwFub6D8AAAAASJLwPwAAAKDLhABAAAAAADMZ8T8AAAAgIMIAQP////8u3QlAAAAAwAV4AkAAAADg7lwCQAAAAMBbm+g/AAAAAEiS8D8AAACgy4QAQAAAAAAzGfE/AAAAICDCAED/////Lt0JQAAAAMAFeAJAAAAA4O5cAkAAAADAW5voPwAAAABIkvA/AAAAoMuEAEAAAAAAMxnxPwAAACAgwgBA/////y7dCUAAAADABXgCQAAAAODuXAJAAAAAwFub6D8AAAAASJLwPwAAAKDLhABAAAAAADMZ8T8AAAAgIMIAQP////8u3QlAAAAAwAV4AkAAAADg7lwCQAAAAMBbm+g/AAAAAEiS8D8AAACgy4QAQAAAAAAzGfE/AAAAICDCAED/////Lt0JQAAAAMAFeAJAAAAA4O5cAkAAAADAW5voPwAAAABIkvA/AAAAoMuEAEAAAAAAMxnxPwAAACAgwgBA/////y7dCUAAAADABXgCQAAAAODuXAJAAAAAwFub6D8AAAAASJLwPwAAAKDLhABAAAAAADMZ8T8AAAAgIMIAQP////8u3QlAAAAAwAV4AkAAAADg7lwCQAAAAMBbm+g/AAAAAEiS8D8AAACgy4QAQAAAAAAzGfE/AAAAICDCAED/////Lt0JQAAAAMAFeAJAAAAA4O5cAkAAAADAW5voPwAAAABIkvA/AAAAoMuEAEAAAAAAMxnxPwAAACAgwgBA/////y7dCUAAAADABXgCQAAAAODuXAJAAAAAwFub6D8AAAAASJLwPwAAAKDLhABAAAAAADMZ8T8AAAAgIMIAQP////8u3QlAAAAAwAV4AkAAAADg7lwCQAAAAMBbm+g/AAAAAEiS8D8AAACgy4QAQAAAAAAzGfE/AAAAICDCAED/////Lt0JQAAAAMAFeAJAAAAA4O5cAkAAAADAW5voPwAAAABIkvA/AAAAoMuEAEAAAAAAMxnxPwAAACAgwgBA/////y7dCUAAAADABXgCQAAAAODuXAJAAAAAwFub6D8AAAAASJLwPwAAAKDLhABAAAAAADMZ8T8AAAAgIMIAQP////8u3QlAAAAAwAV4AkAAAADg7lwCQAAAAMBbm+g/AAAAAEiS8D8AAACgy4QAQAAAAAAzGfE/AAAAICDCAED/////Lt0JQAAAAMAFeAJAAAAA4O5cAkAAAADAW5voPwAAAABIkvA/AAAAoMuEAEAAAAAAMxnxPw==\",\"dtype\":\"float64\",\"shape\":[200]},\"index\":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199],\"label\":[\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\"],\"layer_num\":[0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8,9,9,9,9,9,9,9,9,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,13,13,13,13,13,13,13,13,14,14,14,14,14,14,14,14,15,15,15,15,15,15,15,15,16,16,16,16,16,16,16,16,17,17,17,17,17,17,17,17,18,18,18,18,18,18,18,18,19,19,19,19,19,19,19,19,20,20,20,20,20,20,20,20,21,21,21,21,21,21,21,21,22,22,22,22,22,22,22,22,23,23,23,23,23,23,23,23,24,24,24,24,24,24,24,24],\"layer_weight\":[0.31732210516929626,0.07503759860992432,0.2977501153945923,0.08463462442159653,0.3475206792354584,0.3087686002254486,0.15112213790416718,0.2875621020793915,0.4917048215866089,0.8489028811454773,0.4384748637676239,0.8338761925697327,0.49752989411354065,0.36392515897750854,0.7295767664909363,0.3562931716442108,0.19097307324409485,0.0760594829916954,0.2637750506401062,0.0814892128109932,0.15494942665100098,0.32730621099472046,0.11930105835199356,0.3561447262763977,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0],\"run\":[\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\"],\"scalar_set\":[\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\"],\"tag\":[\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\"],\"task\":[\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\"],\"weight_entropy\":[1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511],\"weight_exp_layer\":{\"__ndarray__\":\"AAAA4PL06z8AAAB8LwTwPwAAADCt6e4/AAAAqDvm7z8AAADQdNbpPwAAABDuS/A/AAAASFL77j8AAAAY6hjxPwAAAODy9Os/AAAAfC8E8D8AAAAwrenuPwAAAKg75u8/AAAA0HTW6T8AAAAQ7kvwPwAAAEhS++4/AAAAGOoY8T8AAADg8vTrPwAAAHwvBPA/AAAAMK3p7j8AAACoO+bvPwAAANB01uk/AAAAEO5L8D8AAABIUvvuPwAAABjqGPE/AAAA4PL06z8AAAB8LwTwPwAAADCt6e4/AAAAqDvm7z8AAADQdNbpPwAAABDuS/A/AAAASFL77j8AAAAY6hjxPwAAAODy9Os/AAAAfC8E8D8AAAAwrenuPwAAAKg75u8/AAAA0HTW6T8AAAAQ7kvwPwAAAEhS++4/AAAAGOoY8T8AAADg8vTrPwAAAHwvBPA/AAAAMK3p7j8AAACoO+bvPwAAANB01uk/AAAAEO5L8D8AAABIUvvuPwAAABjqGPE/AAAA4PL06z8AAAB8LwTwPwAAADCt6e4/AAAAqDvm7z8AAADQdNbpPwAAABDuS/A/AAAASFL77j8AAAAY6hjxPwAAAODy9Os/AAAAfC8E8D8AAAAwrenuPwAAAKg75u8/AAAA0HTW6T8AAAAQ7kvwPwAAAEhS++4/AAAAGOoY8T8AAADg8vTrPwAAAHwvBPA/AAAAMK3p7j8AAACoO+bvPwAAANB01uk/AAAAEO5L8D8AAABIUvvuPwAAABjqGPE/AAAA4PL06z8AAAB8LwTwPwAAADCt6e4/AAAAqDvm7z8AAADQdNbpPwAAABDuS/A/AAAASFL77j8AAAAY6hjxPwAAAODy9Os/AAAAfC8E8D8AAAAwrenuPwAAAKg75u8/AAAA0HTW6T8AAAAQ7kvwPwAAAEhS++4/AAAAGOoY8T8AAADg8vTrPwAAAHwvBPA/AAAAMK3p7j8AAACoO+bvPwAAANB01uk/AAAAEO5L8D8AAABIUvvuPwAAABjqGPE/AAAA4PL06z8AAAB8LwTwPwAAADCt6e4/AAAAqDvm7z8AAADQdNbpPwAAABDuS/A/AAAASFL77j8AAAAY6hjxPwAAAODy9Os/AAAAfC8E8D8AAAAwrenuPwAAAKg75u8/AAAA0HTW6T8AAAAQ7kvwPwAAAEhS++4/AAAAGOoY8T8AAADg8vTrPwAAAHwvBPA/AAAAMK3p7j8AAACoO+bvPwAAANB01uk/AAAAEO5L8D8AAABIUvvuPwAAABjqGPE/AAAA4PL06z8AAAB8LwTwPwAAADCt6e4/AAAAqDvm7z8AAADQdNbpPwAAABDuS/A/AAAASFL77j8AAAAY6hjxPwAAAODy9Os/AAAAfC8E8D8AAAAwrenuPwAAAKg75u8/AAAA0HTW6T8AAAAQ7kvwPwAAAEhS++4/AAAAGOoY8T8AAADg8vTrPwAAAHwvBPA/AAAAMK3p7j8AAACoO+bvPwAAANB01uk/AAAAEO5L8D8AAABIUvvuPwAAABjqGPE/AAAA4PL06z8AAAB8LwTwPwAAADCt6e4/AAAAqDvm7z8AAADQdNbpPwAAABDuS/A/AAAASFL77j8AAAAY6hjxPwAAAODy9Os/AAAAfC8E8D8AAAAwrenuPwAAAKg75u8/AAAA0HTW6T8AAAAQ7kvwPwAAAEhS++4/AAAAGOoY8T8AAADg8vTrPwAAAHwvBPA/AAAAMK3p7j8AAACoO+bvPwAAANB01uk/AAAAEO5L8D8AAABIUvvuPwAAABjqGPE/AAAA4PL06z8AAAB8LwTwPwAAADCt6e4/AAAAqDvm7z8AAADQdNbpPwAAABDuS/A/AAAASFL77j8AAAAY6hjxPwAAAODy9Os/AAAAfC8E8D8AAAAwrenuPwAAAKg75u8/AAAA0HTW6T8AAAAQ7kvwPwAAAEhS++4/AAAAGOoY8T8AAADg8vTrPwAAAHwvBPA/AAAAMK3p7j8AAACoO+bvPwAAANB01uk/AAAAEO5L8D8AAABIUvvuPwAAABjqGPE/AAAA4PL06z8AAAB8LwTwPwAAADCt6e4/AAAAqDvm7z8AAADQdNbpPwAAABDuS/A/AAAASFL77j8AAAAY6hjxPw==\",\"dtype\":\"float64\",\"shape\":[200]},\"weight_exp_layer_oneplus\":{\"__ndarray__\":\"O9rh39F59D+M1ZY80FDxPzMc3xyEAvY/cfUrH6Rs8T/uGL6ytczzP4UiQhyBk/c/T0HUjaY/8j+oZuXSkv/3Pzva4d/RefQ/jNWWPNBQ8T8zHN8chAL2P3H1Kx+kbPE/7hi+srXM8z+FIkIcgZP3P09B1I2mP/I/qGbl0pL/9z872uHf0Xn0P4zVljzQUPE/MxzfHIQC9j9x9SsfpGzxP+4YvrK1zPM/hSJCHIGT9z9PQdSNpj/yP6hm5dKS//c/O9rh39F59D+M1ZY80FDxPzMc3xyEAvY/cfUrH6Rs8T/uGL6ytczzP4UiQhyBk/c/T0HUjaY/8j+oZuXSkv/3Pzva4d/RefQ/jNWWPNBQ8T8zHN8chAL2P3H1Kx+kbPE/7hi+srXM8z+FIkIcgZP3P09B1I2mP/I/qGbl0pL/9z872uHf0Xn0P4zVljzQUPE/MxzfHIQC9j9x9SsfpGzxP+4YvrK1zPM/hSJCHIGT9z9PQdSNpj/yP6hm5dKS//c/O9rh39F59D+M1ZY80FDxPzMc3xyEAvY/cfUrH6Rs8T/uGL6ytczzP4UiQhyBk/c/T0HUjaY/8j+oZuXSkv/3Pzva4d/RefQ/jNWWPNBQ8T8zHN8chAL2P3H1Kx+kbPE/7hi+srXM8z+FIkIcgZP3P09B1I2mP/I/qGbl0pL/9z872uHf0Xn0P4zVljzQUPE/MxzfHIQC9j9x9SsfpGzxP+4YvrK1zPM/hSJCHIGT9z9PQdSNpj/yP6hm5dKS//c/O9rh39F59D+M1ZY80FDxPzMc3xyEAvY/cfUrH6Rs8T/uGL6ytczzP4UiQhyBk/c/T0HUjaY/8j+oZuXSkv/3Pzva4d/RefQ/jNWWPNBQ8T8zHN8chAL2P3H1Kx+kbPE/7hi+srXM8z+FIkIcgZP3P09B1I2mP/I/qGbl0pL/9z872uHf0Xn0P4zVljzQUPE/MxzfHIQC9j9x9SsfpGzxP+4YvrK1zPM/hSJCHIGT9z9PQdSNpj/yP6hm5dKS//c/O9rh39F59D+M1ZY80FDxPzMc3xyEAvY/cfUrH6Rs8T/uGL6ytczzP4UiQhyBk/c/T0HUjaY/8j+oZuXSkv/3Pzva4d/RefQ/jNWWPNBQ8T8zHN8chAL2P3H1Kx+kbPE/7hi+srXM8z+FIkIcgZP3P09B1I2mP/I/qGbl0pL/9z872uHf0Xn0P4zVljzQUPE/MxzfHIQC9j9x9SsfpGzxP+4YvrK1zPM/hSJCHIGT9z9PQdSNpj/yP6hm5dKS//c/O9rh39F59D+M1ZY80FDxPzMc3xyEAvY/cfUrH6Rs8T/uGL6ytczzP4UiQhyBk/c/T0HUjaY/8j+oZuXSkv/3Pzva4d/RefQ/jNWWPNBQ8T8zHN8chAL2P3H1Kx+kbPE/7hi+srXM8z+FIkIcgZP3P09B1I2mP/I/qGbl0pL/9z872uHf0Xn0P4zVljzQUPE/MxzfHIQC9j9x9SsfpGzxP+4YvrK1zPM/hSJCHIGT9z9PQdSNpj/yP6hm5dKS//c/O9rh39F59D+M1ZY80FDxPzMc3xyEAvY/cfUrH6Rs8T/uGL6ytczzP4UiQhyBk/c/T0HUjaY/8j+oZuXSkv/3Pzva4d/RefQ/jNWWPNBQ8T8zHN8chAL2P3H1Kx+kbPE/7hi+srXM8z+FIkIcgZP3P09B1I2mP/I/qGbl0pL/9z872uHf0Xn0P4zVljzQUPE/MxzfHIQC9j9x9SsfpGzxP+4YvrK1zPM/hSJCHIGT9z9PQdSNpj/yP6hm5dKS//c/O9rh39F59D+M1ZY80FDxPzMc3xyEAvY/cfUrH6Rs8T/uGL6ytczzP4UiQhyBk/c/T0HUjaY/8j+oZuXSkv/3Pzva4d/RefQ/jNWWPNBQ8T8zHN8chAL2P3H1Kx+kbPE/7hi+srXM8z+FIkIcgZP3P09B1I2mP/I/qGbl0pL/9z872uHf0Xn0P4zVljzQUPE/MxzfHIQC9j9x9SsfpGzxP+4YvrK1zPM/hSJCHIGT9z9PQdSNpj/yP6hm5dKS//c/O9rh39F59D+M1ZY80FDxPzMc3xyEAvY/cfUrH6Rs8T/uGL6ytczzP4UiQhyBk/c/T0HUjaY/8j+oZuXSkv/3Pw==\",\"dtype\":\"float64\",\"shape\":[200]},\"weight_kl_unif\":{\"__ndarray__\":\"zYnp3eiJuT+ILOEcBUjqP3rt0nOxXaI/+HX9RtWk6D/tXl6Tmo3BP+8H2W1puWs/Xc9di0Vp3j/ge2yqK5B8P82J6d3oibk/iCzhHAVI6j967dJzsV2iP/h1/UbVpOg/7V5ek5qNwT/vB9ltablrP13PXYtFad4/4HtsqiuQfD/Niend6Im5P4gs4RwFSOo/eu3Sc7Fdoj/4df1G1aToP+1eXpOajcE/7wfZbWm5az9dz12LRWneP+B7bKorkHw/zYnp3eiJuT+ILOEcBUjqP3rt0nOxXaI/+HX9RtWk6D/tXl6Tmo3BP+8H2W1puWs/Xc9di0Vp3j/ge2yqK5B8P82J6d3oibk/iCzhHAVI6j967dJzsV2iP/h1/UbVpOg/7V5ek5qNwT/vB9ltablrP13PXYtFad4/4HtsqiuQfD/Niend6Im5P4gs4RwFSOo/eu3Sc7Fdoj/4df1G1aToP+1eXpOajcE/7wfZbWm5az9dz12LRWneP+B7bKorkHw/zYnp3eiJuT+ILOEcBUjqP3rt0nOxXaI/+HX9RtWk6D/tXl6Tmo3BP+8H2W1puWs/Xc9di0Vp3j/ge2yqK5B8P82J6d3oibk/iCzhHAVI6j967dJzsV2iP/h1/UbVpOg/7V5ek5qNwT/vB9ltablrP13PXYtFad4/4HtsqiuQfD/Niend6Im5P4gs4RwFSOo/eu3Sc7Fdoj/4df1G1aToP+1eXpOajcE/7wfZbWm5az9dz12LRWneP+B7bKorkHw/zYnp3eiJuT+ILOEcBUjqP3rt0nOxXaI/+HX9RtWk6D/tXl6Tmo3BP+8H2W1puWs/Xc9di0Vp3j/ge2yqK5B8P82J6d3oibk/iCzhHAVI6j967dJzsV2iP/h1/UbVpOg/7V5ek5qNwT/vB9ltablrP13PXYtFad4/4HtsqiuQfD/Niend6Im5P4gs4RwFSOo/eu3Sc7Fdoj/4df1G1aToP+1eXpOajcE/7wfZbWm5az9dz12LRWneP+B7bKorkHw/zYnp3eiJuT+ILOEcBUjqP3rt0nOxXaI/+HX9RtWk6D/tXl6Tmo3BP+8H2W1puWs/Xc9di0Vp3j/ge2yqK5B8P82J6d3oibk/iCzhHAVI6j967dJzsV2iP/h1/UbVpOg/7V5ek5qNwT/vB9ltablrP13PXYtFad4/4HtsqiuQfD/Niend6Im5P4gs4RwFSOo/eu3Sc7Fdoj/4df1G1aToP+1eXpOajcE/7wfZbWm5az9dz12LRWneP+B7bKorkHw/zYnp3eiJuT+ILOEcBUjqP3rt0nOxXaI/+HX9RtWk6D/tXl6Tmo3BP+8H2W1puWs/Xc9di0Vp3j/ge2yqK5B8P82J6d3oibk/iCzhHAVI6j967dJzsV2iP/h1/UbVpOg/7V5ek5qNwT/vB9ltablrP13PXYtFad4/4HtsqiuQfD/Niend6Im5P4gs4RwFSOo/eu3Sc7Fdoj/4df1G1aToP+1eXpOajcE/7wfZbWm5az9dz12LRWneP+B7bKorkHw/zYnp3eiJuT+ILOEcBUjqP3rt0nOxXaI/+HX9RtWk6D/tXl6Tmo3BP+8H2W1puWs/Xc9di0Vp3j/ge2yqK5B8P82J6d3oibk/iCzhHAVI6j967dJzsV2iP/h1/UbVpOg/7V5ek5qNwT/vB9ltablrP13PXYtFad4/4HtsqiuQfD/Niend6Im5P4gs4RwFSOo/eu3Sc7Fdoj/4df1G1aToP+1eXpOajcE/7wfZbWm5az9dz12LRWneP+B7bKorkHw/zYnp3eiJuT+ILOEcBUjqP3rt0nOxXaI/+HX9RtWk6D/tXl6Tmo3BP+8H2W1puWs/Xc9di0Vp3j/ge2yqK5B8P82J6d3oibk/iCzhHAVI6j967dJzsV2iP/h1/UbVpOg/7V5ek5qNwT/vB9ltablrP13PXYtFad4/4HtsqiuQfD/Niend6Im5P4gs4RwFSOo/eu3Sc7Fdoj/4df1G1aToP+1eXpOajcE/7wfZbWm5az9dz12LRWneP+B7bKorkHw/zYnp3eiJuT+ILOEcBUjqP3rt0nOxXaI/+HX9RtWk6D/tXl6Tmo3BP+8H2W1puWs/Xc9di0Vp3j/ge2yqK5B8Pw==\",\"dtype\":\"float64\",\"shape\":[200]}},\"selected\":{\"id\":\"7584\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"7585\",\"type\":\"UnionRenderers\"}},\"id\":\"7257\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"field\":\"_fill_color\"},\"height\":{\"field\":\"_bar_height\",\"units\":\"data\"},\"line_color\":{\"field\":\"_line_color\"},\"line_width\":{\"value\":1.5},\"width\":{\"units\":\"data\",\"value\":0.9},\"x\":{\"field\":\"layer_num\"},\"y\":{\"field\":\"_bar_center\",\"transform\":{\"id\":\"7263\",\"type\":\"Dodge\"}}},\"id\":\"7266\",\"type\":\"Rect\"},{\"attributes\":{},\"id\":\"7590\",\"type\":\"Selection\"},{\"attributes\":{\"dimension\":1,\"plot\":{\"id\":\"7215\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"ticker\":{\"id\":\"7229\",\"type\":\"CategoricalTicker\"}},\"id\":\"7231\",\"type\":\"Grid\"},{\"attributes\":{\"source\":{\"id\":\"7250\",\"type\":\"ColumnDataSource\"}},\"id\":\"7256\",\"type\":\"CDSView\"},{\"attributes\":{},\"id\":\"7588\",\"type\":\"Selection\"},{\"attributes\":{\"data_source\":{\"id\":\"7250\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"7252\",\"type\":\"Rect\"},\"hover_glyph\":{\"id\":\"7254\",\"type\":\"Rect\"},\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"7253\",\"type\":\"Rect\"},\"selection_glyph\":null,\"view\":{\"id\":\"7256\",\"type\":\"CDSView\"}},\"id\":\"7255\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.7},\"fill_color\":{\"value\":\"firebrick\"},\"height\":{\"field\":\"_bar_height\",\"units\":\"data\"},\"line_color\":{\"value\":\"#1f77b4\"},\"line_width\":{\"value\":1.5},\"width\":{\"units\":\"data\",\"value\":0.9},\"x\":{\"field\":\"layer_num\"},\"y\":{\"field\":\"_bar_center\",\"transform\":{\"id\":\"7263\",\"type\":\"Dodge\"}}},\"id\":\"7268\",\"type\":\"Rect\"},{\"attributes\":{\"source\":{\"id\":\"7237\",\"type\":\"ColumnDataSource\"}},\"id\":\"7242\",\"type\":\"CDSView\"},{\"attributes\":{},\"id\":\"7591\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"fill_color\":{\"value\":\"firebrick\"},\"height\":{\"field\":\"_bar_height\",\"units\":\"data\"},\"line_color\":{\"value\":\"#1f77b4\"},\"width\":{\"units\":\"data\",\"value\":0.9},\"x\":{\"field\":\"layer_num\"},\"y\":{\"field\":\"_bar_center\",\"transform\":{\"id\":\"7249\",\"type\":\"Dodge\"}}},\"id\":\"7254\",\"type\":\"Rect\"},{\"attributes\":{},\"id\":\"7229\",\"type\":\"CategoricalTicker\"},{\"attributes\":{\"callback\":null,\"data\":{\"_bar_center\":[\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\"],\"_bar_height\":[0.31732210516929626,0.07503759860992432,0.2977501153945923,0.08463462442159653,0.3475206792354584,0.3087686002254486,0.15112213790416718,0.2875621020793915,0.4917048215866089,0.8489028811454773,0.4384748637676239,0.8338761925697327,0.49752989411354065,0.36392515897750854,0.7295767664909363,0.3562931716442108,0.19097307324409485,0.0760594829916954,0.2637750506401062,0.0814892128109932,0.15494942665100098,0.32730621099472046,0.11930105835199356,0.3561447262763977,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0],\"_display_name\":[\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\"],\"_formatted_entropy\":[\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\"],\"_formatted_kl_unif\":[\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\"],\"checkpoint\":[\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\"],\"display_col\":[\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\"],\"exp_name\":[\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\"],\"exp_type\":[\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\"],\"gamma\":{\"__ndarray__\":\"AAAAICDCAED/////Lt0JQAAAAMAFeAJAAAAA4O5cAkAAAADAW5voPwAAAABIkvA/AAAAoMuEAEAAAAAAMxnxPwAAACAgwgBA/////y7dCUAAAADABXgCQAAAAODuXAJAAAAAwFub6D8AAAAASJLwPwAAAKDLhABAAAAAADMZ8T8AAAAgIMIAQP////8u3QlAAAAAwAV4AkAAAADg7lwCQAAAAMBbm+g/AAAAAEiS8D8AAACgy4QAQAAAAAAzGfE/AAAAICDCAED/////Lt0JQAAAAMAFeAJAAAAA4O5cAkAAAADAW5voPwAAAABIkvA/AAAAoMuEAEAAAAAAMxnxPwAAACAgwgBA/////y7dCUAAAADABXgCQAAAAODuXAJAAAAAwFub6D8AAAAASJLwPwAAAKDLhABAAAAAADMZ8T8AAAAgIMIAQP////8u3QlAAAAAwAV4AkAAAADg7lwCQAAAAMBbm+g/AAAAAEiS8D8AAACgy4QAQAAAAAAzGfE/AAAAICDCAED/////Lt0JQAAAAMAFeAJAAAAA4O5cAkAAAADAW5voPwAAAABIkvA/AAAAoMuEAEAAAAAAMxnxPwAAACAgwgBA/////y7dCUAAAADABXgCQAAAAODuXAJAAAAAwFub6D8AAAAASJLwPwAAAKDLhABAAAAAADMZ8T8AAAAgIMIAQP////8u3QlAAAAAwAV4AkAAAADg7lwCQAAAAMBbm+g/AAAAAEiS8D8AAACgy4QAQAAAAAAzGfE/AAAAICDCAED/////Lt0JQAAAAMAFeAJAAAAA4O5cAkAAAADAW5voPwAAAABIkvA/AAAAoMuEAEAAAAAAMxnxPwAAACAgwgBA/////y7dCUAAAADABXgCQAAAAODuXAJAAAAAwFub6D8AAAAASJLwPwAAAKDLhABAAAAAADMZ8T8AAAAgIMIAQP////8u3QlAAAAAwAV4AkAAAADg7lwCQAAAAMBbm+g/AAAAAEiS8D8AAACgy4QAQAAAAAAzGfE/AAAAICDCAED/////Lt0JQAAAAMAFeAJAAAAA4O5cAkAAAADAW5voPwAAAABIkvA/AAAAoMuEAEAAAAAAMxnxPwAAACAgwgBA/////y7dCUAAAADABXgCQAAAAODuXAJAAAAAwFub6D8AAAAASJLwPwAAAKDLhABAAAAAADMZ8T8AAAAgIMIAQP////8u3QlAAAAAwAV4AkAAAADg7lwCQAAAAMBbm+g/AAAAAEiS8D8AAACgy4QAQAAAAAAzGfE/AAAAICDCAED/////Lt0JQAAAAMAFeAJAAAAA4O5cAkAAAADAW5voPwAAAABIkvA/AAAAoMuEAEAAAAAAMxnxPwAAACAgwgBA/////y7dCUAAAADABXgCQAAAAODuXAJAAAAAwFub6D8AAAAASJLwPwAAAKDLhABAAAAAADMZ8T8AAAAgIMIAQP////8u3QlAAAAAwAV4AkAAAADg7lwCQAAAAMBbm+g/AAAAAEiS8D8AAACgy4QAQAAAAAAzGfE/AAAAICDCAED/////Lt0JQAAAAMAFeAJAAAAA4O5cAkAAAADAW5voPwAAAABIkvA/AAAAoMuEAEAAAAAAMxnxPwAAACAgwgBA/////y7dCUAAAADABXgCQAAAAODuXAJAAAAAwFub6D8AAAAASJLwPwAAAKDLhABAAAAAADMZ8T8AAAAgIMIAQP////8u3QlAAAAAwAV4AkAAAADg7lwCQAAAAMBbm+g/AAAAAEiS8D8AAACgy4QAQAAAAAAzGfE/AAAAICDCAED/////Lt0JQAAAAMAFeAJAAAAA4O5cAkAAAADAW5voPwAAAABIkvA/AAAAoMuEAEAAAAAAMxnxPwAAACAgwgBA/////y7dCUAAAADABXgCQAAAAODuXAJAAAAAwFub6D8AAAAASJLwPwAAAKDLhABAAAAAADMZ8T8AAAAgIMIAQP////8u3QlAAAAAwAV4AkAAAADg7lwCQAAAAMBbm+g/AAAAAEiS8D8AAACgy4QAQAAAAAAzGfE/AAAAICDCAED/////Lt0JQAAAAMAFeAJAAAAA4O5cAkAAAADAW5voPwAAAABIkvA/AAAAoMuEAEAAAAAAMxnxPw==\",\"dtype\":\"float64\",\"shape\":[200]},\"index\":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199],\"label\":[\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\"],\"layer_num\":[0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8,9,9,9,9,9,9,9,9,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,13,13,13,13,13,13,13,13,14,14,14,14,14,14,14,14,15,15,15,15,15,15,15,15,16,16,16,16,16,16,16,16,17,17,17,17,17,17,17,17,18,18,18,18,18,18,18,18,19,19,19,19,19,19,19,19,20,20,20,20,20,20,20,20,21,21,21,21,21,21,21,21,22,22,22,22,22,22,22,22,23,23,23,23,23,23,23,23,24,24,24,24,24,24,24,24],\"layer_weight\":[0.31732210516929626,0.07503759860992432,0.2977501153945923,0.08463462442159653,0.3475206792354584,0.3087686002254486,0.15112213790416718,0.2875621020793915,0.4917048215866089,0.8489028811454773,0.4384748637676239,0.8338761925697327,0.49752989411354065,0.36392515897750854,0.7295767664909363,0.3562931716442108,0.19097307324409485,0.0760594829916954,0.2637750506401062,0.0814892128109932,0.15494942665100098,0.32730621099472046,0.11930105835199356,0.3561447262763977,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0],\"run\":[\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\"],\"scalar_set\":[\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\"],\"tag\":[\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\"],\"task\":[\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\"],\"weight_entropy\":[1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511],\"weight_exp_layer\":{\"__ndarray__\":\"AAAA4PL06z8AAAB8LwTwPwAAADCt6e4/AAAAqDvm7z8AAADQdNbpPwAAABDuS/A/AAAASFL77j8AAAAY6hjxPwAAAODy9Os/AAAAfC8E8D8AAAAwrenuPwAAAKg75u8/AAAA0HTW6T8AAAAQ7kvwPwAAAEhS++4/AAAAGOoY8T8AAADg8vTrPwAAAHwvBPA/AAAAMK3p7j8AAACoO+bvPwAAANB01uk/AAAAEO5L8D8AAABIUvvuPwAAABjqGPE/AAAA4PL06z8AAAB8LwTwPwAAADCt6e4/AAAAqDvm7z8AAADQdNbpPwAAABDuS/A/AAAASFL77j8AAAAY6hjxPwAAAODy9Os/AAAAfC8E8D8AAAAwrenuPwAAAKg75u8/AAAA0HTW6T8AAAAQ7kvwPwAAAEhS++4/AAAAGOoY8T8AAADg8vTrPwAAAHwvBPA/AAAAMK3p7j8AAACoO+bvPwAAANB01uk/AAAAEO5L8D8AAABIUvvuPwAAABjqGPE/AAAA4PL06z8AAAB8LwTwPwAAADCt6e4/AAAAqDvm7z8AAADQdNbpPwAAABDuS/A/AAAASFL77j8AAAAY6hjxPwAAAODy9Os/AAAAfC8E8D8AAAAwrenuPwAAAKg75u8/AAAA0HTW6T8AAAAQ7kvwPwAAAEhS++4/AAAAGOoY8T8AAADg8vTrPwAAAHwvBPA/AAAAMK3p7j8AAACoO+bvPwAAANB01uk/AAAAEO5L8D8AAABIUvvuPwAAABjqGPE/AAAA4PL06z8AAAB8LwTwPwAAADCt6e4/AAAAqDvm7z8AAADQdNbpPwAAABDuS/A/AAAASFL77j8AAAAY6hjxPwAAAODy9Os/AAAAfC8E8D8AAAAwrenuPwAAAKg75u8/AAAA0HTW6T8AAAAQ7kvwPwAAAEhS++4/AAAAGOoY8T8AAADg8vTrPwAAAHwvBPA/AAAAMK3p7j8AAACoO+bvPwAAANB01uk/AAAAEO5L8D8AAABIUvvuPwAAABjqGPE/AAAA4PL06z8AAAB8LwTwPwAAADCt6e4/AAAAqDvm7z8AAADQdNbpPwAAABDuS/A/AAAASFL77j8AAAAY6hjxPwAAAODy9Os/AAAAfC8E8D8AAAAwrenuPwAAAKg75u8/AAAA0HTW6T8AAAAQ7kvwPwAAAEhS++4/AAAAGOoY8T8AAADg8vTrPwAAAHwvBPA/AAAAMK3p7j8AAACoO+bvPwAAANB01uk/AAAAEO5L8D8AAABIUvvuPwAAABjqGPE/AAAA4PL06z8AAAB8LwTwPwAAADCt6e4/AAAAqDvm7z8AAADQdNbpPwAAABDuS/A/AAAASFL77j8AAAAY6hjxPwAAAODy9Os/AAAAfC8E8D8AAAAwrenuPwAAAKg75u8/AAAA0HTW6T8AAAAQ7kvwPwAAAEhS++4/AAAAGOoY8T8AAADg8vTrPwAAAHwvBPA/AAAAMK3p7j8AAACoO+bvPwAAANB01uk/AAAAEO5L8D8AAABIUvvuPwAAABjqGPE/AAAA4PL06z8AAAB8LwTwPwAAADCt6e4/AAAAqDvm7z8AAADQdNbpPwAAABDuS/A/AAAASFL77j8AAAAY6hjxPwAAAODy9Os/AAAAfC8E8D8AAAAwrenuPwAAAKg75u8/AAAA0HTW6T8AAAAQ7kvwPwAAAEhS++4/AAAAGOoY8T8AAADg8vTrPwAAAHwvBPA/AAAAMK3p7j8AAACoO+bvPwAAANB01uk/AAAAEO5L8D8AAABIUvvuPwAAABjqGPE/AAAA4PL06z8AAAB8LwTwPwAAADCt6e4/AAAAqDvm7z8AAADQdNbpPwAAABDuS/A/AAAASFL77j8AAAAY6hjxPwAAAODy9Os/AAAAfC8E8D8AAAAwrenuPwAAAKg75u8/AAAA0HTW6T8AAAAQ7kvwPwAAAEhS++4/AAAAGOoY8T8AAADg8vTrPwAAAHwvBPA/AAAAMK3p7j8AAACoO+bvPwAAANB01uk/AAAAEO5L8D8AAABIUvvuPwAAABjqGPE/AAAA4PL06z8AAAB8LwTwPwAAADCt6e4/AAAAqDvm7z8AAADQdNbpPwAAABDuS/A/AAAASFL77j8AAAAY6hjxPw==\",\"dtype\":\"float64\",\"shape\":[200]},\"weight_exp_layer_oneplus\":{\"__ndarray__\":\"O9rh39F59D+M1ZY80FDxPzMc3xyEAvY/cfUrH6Rs8T/uGL6ytczzP4UiQhyBk/c/T0HUjaY/8j+oZuXSkv/3Pzva4d/RefQ/jNWWPNBQ8T8zHN8chAL2P3H1Kx+kbPE/7hi+srXM8z+FIkIcgZP3P09B1I2mP/I/qGbl0pL/9z872uHf0Xn0P4zVljzQUPE/MxzfHIQC9j9x9SsfpGzxP+4YvrK1zPM/hSJCHIGT9z9PQdSNpj/yP6hm5dKS//c/O9rh39F59D+M1ZY80FDxPzMc3xyEAvY/cfUrH6Rs8T/uGL6ytczzP4UiQhyBk/c/T0HUjaY/8j+oZuXSkv/3Pzva4d/RefQ/jNWWPNBQ8T8zHN8chAL2P3H1Kx+kbPE/7hi+srXM8z+FIkIcgZP3P09B1I2mP/I/qGbl0pL/9z872uHf0Xn0P4zVljzQUPE/MxzfHIQC9j9x9SsfpGzxP+4YvrK1zPM/hSJCHIGT9z9PQdSNpj/yP6hm5dKS//c/O9rh39F59D+M1ZY80FDxPzMc3xyEAvY/cfUrH6Rs8T/uGL6ytczzP4UiQhyBk/c/T0HUjaY/8j+oZuXSkv/3Pzva4d/RefQ/jNWWPNBQ8T8zHN8chAL2P3H1Kx+kbPE/7hi+srXM8z+FIkIcgZP3P09B1I2mP/I/qGbl0pL/9z872uHf0Xn0P4zVljzQUPE/MxzfHIQC9j9x9SsfpGzxP+4YvrK1zPM/hSJCHIGT9z9PQdSNpj/yP6hm5dKS//c/O9rh39F59D+M1ZY80FDxPzMc3xyEAvY/cfUrH6Rs8T/uGL6ytczzP4UiQhyBk/c/T0HUjaY/8j+oZuXSkv/3Pzva4d/RefQ/jNWWPNBQ8T8zHN8chAL2P3H1Kx+kbPE/7hi+srXM8z+FIkIcgZP3P09B1I2mP/I/qGbl0pL/9z872uHf0Xn0P4zVljzQUPE/MxzfHIQC9j9x9SsfpGzxP+4YvrK1zPM/hSJCHIGT9z9PQdSNpj/yP6hm5dKS//c/O9rh39F59D+M1ZY80FDxPzMc3xyEAvY/cfUrH6Rs8T/uGL6ytczzP4UiQhyBk/c/T0HUjaY/8j+oZuXSkv/3Pzva4d/RefQ/jNWWPNBQ8T8zHN8chAL2P3H1Kx+kbPE/7hi+srXM8z+FIkIcgZP3P09B1I2mP/I/qGbl0pL/9z872uHf0Xn0P4zVljzQUPE/MxzfHIQC9j9x9SsfpGzxP+4YvrK1zPM/hSJCHIGT9z9PQdSNpj/yP6hm5dKS//c/O9rh39F59D+M1ZY80FDxPzMc3xyEAvY/cfUrH6Rs8T/uGL6ytczzP4UiQhyBk/c/T0HUjaY/8j+oZuXSkv/3Pzva4d/RefQ/jNWWPNBQ8T8zHN8chAL2P3H1Kx+kbPE/7hi+srXM8z+FIkIcgZP3P09B1I2mP/I/qGbl0pL/9z872uHf0Xn0P4zVljzQUPE/MxzfHIQC9j9x9SsfpGzxP+4YvrK1zPM/hSJCHIGT9z9PQdSNpj/yP6hm5dKS//c/O9rh39F59D+M1ZY80FDxPzMc3xyEAvY/cfUrH6Rs8T/uGL6ytczzP4UiQhyBk/c/T0HUjaY/8j+oZuXSkv/3Pzva4d/RefQ/jNWWPNBQ8T8zHN8chAL2P3H1Kx+kbPE/7hi+srXM8z+FIkIcgZP3P09B1I2mP/I/qGbl0pL/9z872uHf0Xn0P4zVljzQUPE/MxzfHIQC9j9x9SsfpGzxP+4YvrK1zPM/hSJCHIGT9z9PQdSNpj/yP6hm5dKS//c/O9rh39F59D+M1ZY80FDxPzMc3xyEAvY/cfUrH6Rs8T/uGL6ytczzP4UiQhyBk/c/T0HUjaY/8j+oZuXSkv/3Pzva4d/RefQ/jNWWPNBQ8T8zHN8chAL2P3H1Kx+kbPE/7hi+srXM8z+FIkIcgZP3P09B1I2mP/I/qGbl0pL/9z872uHf0Xn0P4zVljzQUPE/MxzfHIQC9j9x9SsfpGzxP+4YvrK1zPM/hSJCHIGT9z9PQdSNpj/yP6hm5dKS//c/O9rh39F59D+M1ZY80FDxPzMc3xyEAvY/cfUrH6Rs8T/uGL6ytczzP4UiQhyBk/c/T0HUjaY/8j+oZuXSkv/3Pw==\",\"dtype\":\"float64\",\"shape\":[200]},\"weight_kl_unif\":{\"__ndarray__\":\"zYnp3eiJuT+ILOEcBUjqP3rt0nOxXaI/+HX9RtWk6D/tXl6Tmo3BP+8H2W1puWs/Xc9di0Vp3j/ge2yqK5B8P82J6d3oibk/iCzhHAVI6j967dJzsV2iP/h1/UbVpOg/7V5ek5qNwT/vB9ltablrP13PXYtFad4/4HtsqiuQfD/Niend6Im5P4gs4RwFSOo/eu3Sc7Fdoj/4df1G1aToP+1eXpOajcE/7wfZbWm5az9dz12LRWneP+B7bKorkHw/zYnp3eiJuT+ILOEcBUjqP3rt0nOxXaI/+HX9RtWk6D/tXl6Tmo3BP+8H2W1puWs/Xc9di0Vp3j/ge2yqK5B8P82J6d3oibk/iCzhHAVI6j967dJzsV2iP/h1/UbVpOg/7V5ek5qNwT/vB9ltablrP13PXYtFad4/4HtsqiuQfD/Niend6Im5P4gs4RwFSOo/eu3Sc7Fdoj/4df1G1aToP+1eXpOajcE/7wfZbWm5az9dz12LRWneP+B7bKorkHw/zYnp3eiJuT+ILOEcBUjqP3rt0nOxXaI/+HX9RtWk6D/tXl6Tmo3BP+8H2W1puWs/Xc9di0Vp3j/ge2yqK5B8P82J6d3oibk/iCzhHAVI6j967dJzsV2iP/h1/UbVpOg/7V5ek5qNwT/vB9ltablrP13PXYtFad4/4HtsqiuQfD/Niend6Im5P4gs4RwFSOo/eu3Sc7Fdoj/4df1G1aToP+1eXpOajcE/7wfZbWm5az9dz12LRWneP+B7bKorkHw/zYnp3eiJuT+ILOEcBUjqP3rt0nOxXaI/+HX9RtWk6D/tXl6Tmo3BP+8H2W1puWs/Xc9di0Vp3j/ge2yqK5B8P82J6d3oibk/iCzhHAVI6j967dJzsV2iP/h1/UbVpOg/7V5ek5qNwT/vB9ltablrP13PXYtFad4/4HtsqiuQfD/Niend6Im5P4gs4RwFSOo/eu3Sc7Fdoj/4df1G1aToP+1eXpOajcE/7wfZbWm5az9dz12LRWneP+B7bKorkHw/zYnp3eiJuT+ILOEcBUjqP3rt0nOxXaI/+HX9RtWk6D/tXl6Tmo3BP+8H2W1puWs/Xc9di0Vp3j/ge2yqK5B8P82J6d3oibk/iCzhHAVI6j967dJzsV2iP/h1/UbVpOg/7V5ek5qNwT/vB9ltablrP13PXYtFad4/4HtsqiuQfD/Niend6Im5P4gs4RwFSOo/eu3Sc7Fdoj/4df1G1aToP+1eXpOajcE/7wfZbWm5az9dz12LRWneP+B7bKorkHw/zYnp3eiJuT+ILOEcBUjqP3rt0nOxXaI/+HX9RtWk6D/tXl6Tmo3BP+8H2W1puWs/Xc9di0Vp3j/ge2yqK5B8P82J6d3oibk/iCzhHAVI6j967dJzsV2iP/h1/UbVpOg/7V5ek5qNwT/vB9ltablrP13PXYtFad4/4HtsqiuQfD/Niend6Im5P4gs4RwFSOo/eu3Sc7Fdoj/4df1G1aToP+1eXpOajcE/7wfZbWm5az9dz12LRWneP+B7bKorkHw/zYnp3eiJuT+ILOEcBUjqP3rt0nOxXaI/+HX9RtWk6D/tXl6Tmo3BP+8H2W1puWs/Xc9di0Vp3j/ge2yqK5B8P82J6d3oibk/iCzhHAVI6j967dJzsV2iP/h1/UbVpOg/7V5ek5qNwT/vB9ltablrP13PXYtFad4/4HtsqiuQfD/Niend6Im5P4gs4RwFSOo/eu3Sc7Fdoj/4df1G1aToP+1eXpOajcE/7wfZbWm5az9dz12LRWneP+B7bKorkHw/zYnp3eiJuT+ILOEcBUjqP3rt0nOxXaI/+HX9RtWk6D/tXl6Tmo3BP+8H2W1puWs/Xc9di0Vp3j/ge2yqK5B8P82J6d3oibk/iCzhHAVI6j967dJzsV2iP/h1/UbVpOg/7V5ek5qNwT/vB9ltablrP13PXYtFad4/4HtsqiuQfD/Niend6Im5P4gs4RwFSOo/eu3Sc7Fdoj/4df1G1aToP+1eXpOajcE/7wfZbWm5az9dz12LRWneP+B7bKorkHw/zYnp3eiJuT+ILOEcBUjqP3rt0nOxXaI/+HX9RtWk6D/tXl6Tmo3BP+8H2W1puWs/Xc9di0Vp3j/ge2yqK5B8Pw==\",\"dtype\":\"float64\",\"shape\":[200]}},\"selected\":{\"id\":\"7580\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"7581\",\"type\":\"UnionRenderers\"}},\"id\":\"7243\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"source\":{\"id\":\"7271\",\"type\":\"ColumnDataSource\"}},\"id\":\"7276\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"height\":{\"field\":\"_bar_height\",\"units\":\"data\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"width\":{\"units\":\"data\",\"value\":0.9},\"x\":{\"field\":\"layer_num\"},\"y\":{\"field\":\"_bar_center\",\"transform\":{\"id\":\"7249\",\"type\":\"Dodge\"}}},\"id\":\"7253\",\"type\":\"Rect\"},{\"attributes\":{\"data_source\":{\"id\":\"7271\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"7273\",\"type\":\"Rect\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"7274\",\"type\":\"Rect\"},\"selection_glyph\":null,\"view\":{\"id\":\"7276\",\"type\":\"CDSView\"}},\"id\":\"7275\",\"type\":\"GlyphRenderer\"},{\"attributes\":{},\"id\":\"7592\",\"type\":\"Selection\"},{\"attributes\":{\"formatter\":{\"id\":\"7575\",\"type\":\"CategoricalTickFormatter\"},\"major_label_orientation\":\"vertical\",\"major_label_text_font_size\":{\"value\":\"13pt\"},\"plot\":{\"id\":\"7215\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"ticker\":{\"id\":\"7229\",\"type\":\"CategoricalTicker\"}},\"id\":\"7228\",\"type\":\"CategoricalAxis\"},{\"attributes\":{\"fill_color\":{\"value\":\"#3182bd\"},\"height\":{\"field\":\"_bar_height\",\"units\":\"data\"},\"line_color\":{\"value\":\"#3182bd\"},\"width\":{\"units\":\"data\",\"value\":0.9},\"x\":{\"field\":\"layer_num\"},\"y\":{\"field\":\"_bar_center\",\"transform\":{\"id\":\"7249\",\"type\":\"Dodge\"}}},\"id\":\"7252\",\"type\":\"Rect\"},{\"attributes\":{\"callback\":null,\"data\":{\"_bar_center\":[\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\"],\"_bar_height\":[0.31732210516929626,0.07503759860992432,0.2977501153945923,0.08463462442159653,0.3475206792354584,0.3087686002254486,0.15112213790416718,0.2875621020793915,0.4917048215866089,0.8489028811454773,0.4384748637676239,0.8338761925697327,0.49752989411354065,0.36392515897750854,0.7295767664909363,0.3562931716442108,0.19097307324409485,0.0760594829916954,0.2637750506401062,0.0814892128109932,0.15494942665100098,0.32730621099472046,0.11930105835199356,0.3561447262763977,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0],\"_display_name\":[\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\",\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\"],\"_formatted_entropy\":[\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\"],\"_formatted_kl_unif\":[\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\",\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\"],\"checkpoint\":[\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\"],\"display_col\":[\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\"],\"exp_name\":[\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\",\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\"],\"exp_type\":[\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\"],\"gamma\":{\"__ndarray__\":\"AAAAICDCAED/////Lt0JQAAAAMAFeAJAAAAA4O5cAkAAAADAW5voPwAAAABIkvA/AAAAoMuEAEAAAAAAMxnxPwAAACAgwgBA/////y7dCUAAAADABXgCQAAAAODuXAJAAAAAwFub6D8AAAAASJLwPwAAAKDLhABAAAAAADMZ8T8AAAAgIMIAQP////8u3QlAAAAAwAV4AkAAAADg7lwCQAAAAMBbm+g/AAAAAEiS8D8AAACgy4QAQAAAAAAzGfE/AAAAICDCAED/////Lt0JQAAAAMAFeAJAAAAA4O5cAkAAAADAW5voPwAAAABIkvA/AAAAoMuEAEAAAAAAMxnxPwAAACAgwgBA/////y7dCUAAAADABXgCQAAAAODuXAJAAAAAwFub6D8AAAAASJLwPwAAAKDLhABAAAAAADMZ8T8AAAAgIMIAQP////8u3QlAAAAAwAV4AkAAAADg7lwCQAAAAMBbm+g/AAAAAEiS8D8AAACgy4QAQAAAAAAzGfE/AAAAICDCAED/////Lt0JQAAAAMAFeAJAAAAA4O5cAkAAAADAW5voPwAAAABIkvA/AAAAoMuEAEAAAAAAMxnxPwAAACAgwgBA/////y7dCUAAAADABXgCQAAAAODuXAJAAAAAwFub6D8AAAAASJLwPwAAAKDLhABAAAAAADMZ8T8AAAAgIMIAQP////8u3QlAAAAAwAV4AkAAAADg7lwCQAAAAMBbm+g/AAAAAEiS8D8AAACgy4QAQAAAAAAzGfE/AAAAICDCAED/////Lt0JQAAAAMAFeAJAAAAA4O5cAkAAAADAW5voPwAAAABIkvA/AAAAoMuEAEAAAAAAMxnxPwAAACAgwgBA/////y7dCUAAAADABXgCQAAAAODuXAJAAAAAwFub6D8AAAAASJLwPwAAAKDLhABAAAAAADMZ8T8AAAAgIMIAQP////8u3QlAAAAAwAV4AkAAAADg7lwCQAAAAMBbm+g/AAAAAEiS8D8AAACgy4QAQAAAAAAzGfE/AAAAICDCAED/////Lt0JQAAAAMAFeAJAAAAA4O5cAkAAAADAW5voPwAAAABIkvA/AAAAoMuEAEAAAAAAMxnxPwAAACAgwgBA/////y7dCUAAAADABXgCQAAAAODuXAJAAAAAwFub6D8AAAAASJLwPwAAAKDLhABAAAAAADMZ8T8AAAAgIMIAQP////8u3QlAAAAAwAV4AkAAAADg7lwCQAAAAMBbm+g/AAAAAEiS8D8AAACgy4QAQAAAAAAzGfE/AAAAICDCAED/////Lt0JQAAAAMAFeAJAAAAA4O5cAkAAAADAW5voPwAAAABIkvA/AAAAoMuEAEAAAAAAMxnxPwAAACAgwgBA/////y7dCUAAAADABXgCQAAAAODuXAJAAAAAwFub6D8AAAAASJLwPwAAAKDLhABAAAAAADMZ8T8AAAAgIMIAQP////8u3QlAAAAAwAV4AkAAAADg7lwCQAAAAMBbm+g/AAAAAEiS8D8AAACgy4QAQAAAAAAzGfE/AAAAICDCAED/////Lt0JQAAAAMAFeAJAAAAA4O5cAkAAAADAW5voPwAAAABIkvA/AAAAoMuEAEAAAAAAMxnxPwAAACAgwgBA/////y7dCUAAAADABXgCQAAAAODuXAJAAAAAwFub6D8AAAAASJLwPwAAAKDLhABAAAAAADMZ8T8AAAAgIMIAQP////8u3QlAAAAAwAV4AkAAAADg7lwCQAAAAMBbm+g/AAAAAEiS8D8AAACgy4QAQAAAAAAzGfE/AAAAICDCAED/////Lt0JQAAAAMAFeAJAAAAA4O5cAkAAAADAW5voPwAAAABIkvA/AAAAoMuEAEAAAAAAMxnxPwAAACAgwgBA/////y7dCUAAAADABXgCQAAAAODuXAJAAAAAwFub6D8AAAAASJLwPwAAAKDLhABAAAAAADMZ8T8AAAAgIMIAQP////8u3QlAAAAAwAV4AkAAAADg7lwCQAAAAMBbm+g/AAAAAEiS8D8AAACgy4QAQAAAAAAzGfE/AAAAICDCAED/////Lt0JQAAAAMAFeAJAAAAA4O5cAkAAAADAW5voPwAAAABIkvA/AAAAoMuEAEAAAAAAMxnxPw==\",\"dtype\":\"float64\",\"shape\":[200]},\"index\":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199],\"label\":[\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\"],\"layer_num\":[0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8,9,9,9,9,9,9,9,9,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,13,13,13,13,13,13,13,13,14,14,14,14,14,14,14,14,15,15,15,15,15,15,15,15,16,16,16,16,16,16,16,16,17,17,17,17,17,17,17,17,18,18,18,18,18,18,18,18,19,19,19,19,19,19,19,19,20,20,20,20,20,20,20,20,21,21,21,21,21,21,21,21,22,22,22,22,22,22,22,22,23,23,23,23,23,23,23,23,24,24,24,24,24,24,24,24],\"layer_weight\":[0.31732210516929626,0.07503759860992432,0.2977501153945923,0.08463462442159653,0.3475206792354584,0.3087686002254486,0.15112213790416718,0.2875621020793915,0.4917048215866089,0.8489028811454773,0.4384748637676239,0.8338761925697327,0.49752989411354065,0.36392515897750854,0.7295767664909363,0.3562931716442108,0.19097307324409485,0.0760594829916954,0.2637750506401062,0.0814892128109932,0.15494942665100098,0.32730621099472046,0.11930105835199356,0.3561447262763977,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0],\"run\":[\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\",\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\"],\"scalar_set\":[\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\"],\"tag\":[\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\"],\"task\":[\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\",\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\"],\"weight_entropy\":[1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511,1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511],\"weight_exp_layer\":{\"__ndarray__\":\"AAAA4PL06z8AAAB8LwTwPwAAADCt6e4/AAAAqDvm7z8AAADQdNbpPwAAABDuS/A/AAAASFL77j8AAAAY6hjxPwAAAODy9Os/AAAAfC8E8D8AAAAwrenuPwAAAKg75u8/AAAA0HTW6T8AAAAQ7kvwPwAAAEhS++4/AAAAGOoY8T8AAADg8vTrPwAAAHwvBPA/AAAAMK3p7j8AAACoO+bvPwAAANB01uk/AAAAEO5L8D8AAABIUvvuPwAAABjqGPE/AAAA4PL06z8AAAB8LwTwPwAAADCt6e4/AAAAqDvm7z8AAADQdNbpPwAAABDuS/A/AAAASFL77j8AAAAY6hjxPwAAAODy9Os/AAAAfC8E8D8AAAAwrenuPwAAAKg75u8/AAAA0HTW6T8AAAAQ7kvwPwAAAEhS++4/AAAAGOoY8T8AAADg8vTrPwAAAHwvBPA/AAAAMK3p7j8AAACoO+bvPwAAANB01uk/AAAAEO5L8D8AAABIUvvuPwAAABjqGPE/AAAA4PL06z8AAAB8LwTwPwAAADCt6e4/AAAAqDvm7z8AAADQdNbpPwAAABDuS/A/AAAASFL77j8AAAAY6hjxPwAAAODy9Os/AAAAfC8E8D8AAAAwrenuPwAAAKg75u8/AAAA0HTW6T8AAAAQ7kvwPwAAAEhS++4/AAAAGOoY8T8AAADg8vTrPwAAAHwvBPA/AAAAMK3p7j8AAACoO+bvPwAAANB01uk/AAAAEO5L8D8AAABIUvvuPwAAABjqGPE/AAAA4PL06z8AAAB8LwTwPwAAADCt6e4/AAAAqDvm7z8AAADQdNbpPwAAABDuS/A/AAAASFL77j8AAAAY6hjxPwAAAODy9Os/AAAAfC8E8D8AAAAwrenuPwAAAKg75u8/AAAA0HTW6T8AAAAQ7kvwPwAAAEhS++4/AAAAGOoY8T8AAADg8vTrPwAAAHwvBPA/AAAAMK3p7j8AAACoO+bvPwAAANB01uk/AAAAEO5L8D8AAABIUvvuPwAAABjqGPE/AAAA4PL06z8AAAB8LwTwPwAAADCt6e4/AAAAqDvm7z8AAADQdNbpPwAAABDuS/A/AAAASFL77j8AAAAY6hjxPwAAAODy9Os/AAAAfC8E8D8AAAAwrenuPwAAAKg75u8/AAAA0HTW6T8AAAAQ7kvwPwAAAEhS++4/AAAAGOoY8T8AAADg8vTrPwAAAHwvBPA/AAAAMK3p7j8AAACoO+bvPwAAANB01uk/AAAAEO5L8D8AAABIUvvuPwAAABjqGPE/AAAA4PL06z8AAAB8LwTwPwAAADCt6e4/AAAAqDvm7z8AAADQdNbpPwAAABDuS/A/AAAASFL77j8AAAAY6hjxPwAAAODy9Os/AAAAfC8E8D8AAAAwrenuPwAAAKg75u8/AAAA0HTW6T8AAAAQ7kvwPwAAAEhS++4/AAAAGOoY8T8AAADg8vTrPwAAAHwvBPA/AAAAMK3p7j8AAACoO+bvPwAAANB01uk/AAAAEO5L8D8AAABIUvvuPwAAABjqGPE/AAAA4PL06z8AAAB8LwTwPwAAADCt6e4/AAAAqDvm7z8AAADQdNbpPwAAABDuS/A/AAAASFL77j8AAAAY6hjxPwAAAODy9Os/AAAAfC8E8D8AAAAwrenuPwAAAKg75u8/AAAA0HTW6T8AAAAQ7kvwPwAAAEhS++4/AAAAGOoY8T8AAADg8vTrPwAAAHwvBPA/AAAAMK3p7j8AAACoO+bvPwAAANB01uk/AAAAEO5L8D8AAABIUvvuPwAAABjqGPE/AAAA4PL06z8AAAB8LwTwPwAAADCt6e4/AAAAqDvm7z8AAADQdNbpPwAAABDuS/A/AAAASFL77j8AAAAY6hjxPwAAAODy9Os/AAAAfC8E8D8AAAAwrenuPwAAAKg75u8/AAAA0HTW6T8AAAAQ7kvwPwAAAEhS++4/AAAAGOoY8T8AAADg8vTrPwAAAHwvBPA/AAAAMK3p7j8AAACoO+bvPwAAANB01uk/AAAAEO5L8D8AAABIUvvuPwAAABjqGPE/AAAA4PL06z8AAAB8LwTwPwAAADCt6e4/AAAAqDvm7z8AAADQdNbpPwAAABDuS/A/AAAASFL77j8AAAAY6hjxPw==\",\"dtype\":\"float64\",\"shape\":[200]},\"weight_exp_layer_oneplus\":{\"__ndarray__\":\"O9rh39F59D+M1ZY80FDxPzMc3xyEAvY/cfUrH6Rs8T/uGL6ytczzP4UiQhyBk/c/T0HUjaY/8j+oZuXSkv/3Pzva4d/RefQ/jNWWPNBQ8T8zHN8chAL2P3H1Kx+kbPE/7hi+srXM8z+FIkIcgZP3P09B1I2mP/I/qGbl0pL/9z872uHf0Xn0P4zVljzQUPE/MxzfHIQC9j9x9SsfpGzxP+4YvrK1zPM/hSJCHIGT9z9PQdSNpj/yP6hm5dKS//c/O9rh39F59D+M1ZY80FDxPzMc3xyEAvY/cfUrH6Rs8T/uGL6ytczzP4UiQhyBk/c/T0HUjaY/8j+oZuXSkv/3Pzva4d/RefQ/jNWWPNBQ8T8zHN8chAL2P3H1Kx+kbPE/7hi+srXM8z+FIkIcgZP3P09B1I2mP/I/qGbl0pL/9z872uHf0Xn0P4zVljzQUPE/MxzfHIQC9j9x9SsfpGzxP+4YvrK1zPM/hSJCHIGT9z9PQdSNpj/yP6hm5dKS//c/O9rh39F59D+M1ZY80FDxPzMc3xyEAvY/cfUrH6Rs8T/uGL6ytczzP4UiQhyBk/c/T0HUjaY/8j+oZuXSkv/3Pzva4d/RefQ/jNWWPNBQ8T8zHN8chAL2P3H1Kx+kbPE/7hi+srXM8z+FIkIcgZP3P09B1I2mP/I/qGbl0pL/9z872uHf0Xn0P4zVljzQUPE/MxzfHIQC9j9x9SsfpGzxP+4YvrK1zPM/hSJCHIGT9z9PQdSNpj/yP6hm5dKS//c/O9rh39F59D+M1ZY80FDxPzMc3xyEAvY/cfUrH6Rs8T/uGL6ytczzP4UiQhyBk/c/T0HUjaY/8j+oZuXSkv/3Pzva4d/RefQ/jNWWPNBQ8T8zHN8chAL2P3H1Kx+kbPE/7hi+srXM8z+FIkIcgZP3P09B1I2mP/I/qGbl0pL/9z872uHf0Xn0P4zVljzQUPE/MxzfHIQC9j9x9SsfpGzxP+4YvrK1zPM/hSJCHIGT9z9PQdSNpj/yP6hm5dKS//c/O9rh39F59D+M1ZY80FDxPzMc3xyEAvY/cfUrH6Rs8T/uGL6ytczzP4UiQhyBk/c/T0HUjaY/8j+oZuXSkv/3Pzva4d/RefQ/jNWWPNBQ8T8zHN8chAL2P3H1Kx+kbPE/7hi+srXM8z+FIkIcgZP3P09B1I2mP/I/qGbl0pL/9z872uHf0Xn0P4zVljzQUPE/MxzfHIQC9j9x9SsfpGzxP+4YvrK1zPM/hSJCHIGT9z9PQdSNpj/yP6hm5dKS//c/O9rh39F59D+M1ZY80FDxPzMc3xyEAvY/cfUrH6Rs8T/uGL6ytczzP4UiQhyBk/c/T0HUjaY/8j+oZuXSkv/3Pzva4d/RefQ/jNWWPNBQ8T8zHN8chAL2P3H1Kx+kbPE/7hi+srXM8z+FIkIcgZP3P09B1I2mP/I/qGbl0pL/9z872uHf0Xn0P4zVljzQUPE/MxzfHIQC9j9x9SsfpGzxP+4YvrK1zPM/hSJCHIGT9z9PQdSNpj/yP6hm5dKS//c/O9rh39F59D+M1ZY80FDxPzMc3xyEAvY/cfUrH6Rs8T/uGL6ytczzP4UiQhyBk/c/T0HUjaY/8j+oZuXSkv/3Pzva4d/RefQ/jNWWPNBQ8T8zHN8chAL2P3H1Kx+kbPE/7hi+srXM8z+FIkIcgZP3P09B1I2mP/I/qGbl0pL/9z872uHf0Xn0P4zVljzQUPE/MxzfHIQC9j9x9SsfpGzxP+4YvrK1zPM/hSJCHIGT9z9PQdSNpj/yP6hm5dKS//c/O9rh39F59D+M1ZY80FDxPzMc3xyEAvY/cfUrH6Rs8T/uGL6ytczzP4UiQhyBk/c/T0HUjaY/8j+oZuXSkv/3Pzva4d/RefQ/jNWWPNBQ8T8zHN8chAL2P3H1Kx+kbPE/7hi+srXM8z+FIkIcgZP3P09B1I2mP/I/qGbl0pL/9z872uHf0Xn0P4zVljzQUPE/MxzfHIQC9j9x9SsfpGzxP+4YvrK1zPM/hSJCHIGT9z9PQdSNpj/yP6hm5dKS//c/O9rh39F59D+M1ZY80FDxPzMc3xyEAvY/cfUrH6Rs8T/uGL6ytczzP4UiQhyBk/c/T0HUjaY/8j+oZuXSkv/3Pw==\",\"dtype\":\"float64\",\"shape\":[200]},\"weight_kl_unif\":{\"__ndarray__\":\"zYnp3eiJuT+ILOEcBUjqP3rt0nOxXaI/+HX9RtWk6D/tXl6Tmo3BP+8H2W1puWs/Xc9di0Vp3j/ge2yqK5B8P82J6d3oibk/iCzhHAVI6j967dJzsV2iP/h1/UbVpOg/7V5ek5qNwT/vB9ltablrP13PXYtFad4/4HtsqiuQfD/Niend6Im5P4gs4RwFSOo/eu3Sc7Fdoj/4df1G1aToP+1eXpOajcE/7wfZbWm5az9dz12LRWneP+B7bKorkHw/zYnp3eiJuT+ILOEcBUjqP3rt0nOxXaI/+HX9RtWk6D/tXl6Tmo3BP+8H2W1puWs/Xc9di0Vp3j/ge2yqK5B8P82J6d3oibk/iCzhHAVI6j967dJzsV2iP/h1/UbVpOg/7V5ek5qNwT/vB9ltablrP13PXYtFad4/4HtsqiuQfD/Niend6Im5P4gs4RwFSOo/eu3Sc7Fdoj/4df1G1aToP+1eXpOajcE/7wfZbWm5az9dz12LRWneP+B7bKorkHw/zYnp3eiJuT+ILOEcBUjqP3rt0nOxXaI/+HX9RtWk6D/tXl6Tmo3BP+8H2W1puWs/Xc9di0Vp3j/ge2yqK5B8P82J6d3oibk/iCzhHAVI6j967dJzsV2iP/h1/UbVpOg/7V5ek5qNwT/vB9ltablrP13PXYtFad4/4HtsqiuQfD/Niend6Im5P4gs4RwFSOo/eu3Sc7Fdoj/4df1G1aToP+1eXpOajcE/7wfZbWm5az9dz12LRWneP+B7bKorkHw/zYnp3eiJuT+ILOEcBUjqP3rt0nOxXaI/+HX9RtWk6D/tXl6Tmo3BP+8H2W1puWs/Xc9di0Vp3j/ge2yqK5B8P82J6d3oibk/iCzhHAVI6j967dJzsV2iP/h1/UbVpOg/7V5ek5qNwT/vB9ltablrP13PXYtFad4/4HtsqiuQfD/Niend6Im5P4gs4RwFSOo/eu3Sc7Fdoj/4df1G1aToP+1eXpOajcE/7wfZbWm5az9dz12LRWneP+B7bKorkHw/zYnp3eiJuT+ILOEcBUjqP3rt0nOxXaI/+HX9RtWk6D/tXl6Tmo3BP+8H2W1puWs/Xc9di0Vp3j/ge2yqK5B8P82J6d3oibk/iCzhHAVI6j967dJzsV2iP/h1/UbVpOg/7V5ek5qNwT/vB9ltablrP13PXYtFad4/4HtsqiuQfD/Niend6Im5P4gs4RwFSOo/eu3Sc7Fdoj/4df1G1aToP+1eXpOajcE/7wfZbWm5az9dz12LRWneP+B7bKorkHw/zYnp3eiJuT+ILOEcBUjqP3rt0nOxXaI/+HX9RtWk6D/tXl6Tmo3BP+8H2W1puWs/Xc9di0Vp3j/ge2yqK5B8P82J6d3oibk/iCzhHAVI6j967dJzsV2iP/h1/UbVpOg/7V5ek5qNwT/vB9ltablrP13PXYtFad4/4HtsqiuQfD/Niend6Im5P4gs4RwFSOo/eu3Sc7Fdoj/4df1G1aToP+1eXpOajcE/7wfZbWm5az9dz12LRWneP+B7bKorkHw/zYnp3eiJuT+ILOEcBUjqP3rt0nOxXaI/+HX9RtWk6D/tXl6Tmo3BP+8H2W1puWs/Xc9di0Vp3j/ge2yqK5B8P82J6d3oibk/iCzhHAVI6j967dJzsV2iP/h1/UbVpOg/7V5ek5qNwT/vB9ltablrP13PXYtFad4/4HtsqiuQfD/Niend6Im5P4gs4RwFSOo/eu3Sc7Fdoj/4df1G1aToP+1eXpOajcE/7wfZbWm5az9dz12LRWneP+B7bKorkHw/zYnp3eiJuT+ILOEcBUjqP3rt0nOxXaI/+HX9RtWk6D/tXl6Tmo3BP+8H2W1puWs/Xc9di0Vp3j/ge2yqK5B8P82J6d3oibk/iCzhHAVI6j967dJzsV2iP/h1/UbVpOg/7V5ek5qNwT/vB9ltablrP13PXYtFad4/4HtsqiuQfD/Niend6Im5P4gs4RwFSOo/eu3Sc7Fdoj/4df1G1aToP+1eXpOajcE/7wfZbWm5az9dz12LRWneP+B7bKorkHw/zYnp3eiJuT+ILOEcBUjqP3rt0nOxXaI/+HX9RtWk6D/tXl6Tmo3BP+8H2W1puWs/Xc9di0Vp3j/ge2yqK5B8Pw==\",\"dtype\":\"float64\",\"shape\":[200]}},\"selected\":{\"id\":\"7582\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"7583\",\"type\":\"UnionRenderers\"}},\"id\":\"7250\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"plot\":{\"id\":\"7215\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"ticker\":{\"id\":\"7277\",\"type\":\"FixedTicker\"}},\"id\":\"7227\",\"type\":\"Grid\"},{\"attributes\":{\"data_source\":{\"id\":\"7264\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"7266\",\"type\":\"Rect\"},\"hover_glyph\":{\"id\":\"7268\",\"type\":\"Rect\"},\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"7267\",\"type\":\"Rect\"},\"selection_glyph\":null,\"view\":{\"id\":\"7270\",\"type\":\"CDSView\"}},\"id\":\"7269\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"callback\":null,\"end\":2.5,\"start\":-0.5},\"id\":\"7216\",\"type\":\"Range1d\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"height\":{\"units\":\"data\",\"value\":0.5},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"width\":{\"units\":\"data\",\"value\":0.9},\"x\":{\"field\":\"layer_num\"},\"y\":{\"field\":\"_bar_center\",\"transform\":{\"id\":\"7263\",\"type\":\"Dodge\"}}},\"id\":\"7274\",\"type\":\"Rect\"},{\"attributes\":{\"ticks\":[0,1,2]},\"id\":\"7277\",\"type\":\"FixedTicker\"},{\"attributes\":{\"callback\":null,\"renderers\":[{\"id\":\"7269\",\"type\":\"GlyphRenderer\"},{\"id\":\"7275\",\"type\":\"GlyphRenderer\"}],\"tooltips\":[[\"task\",\"@_display_name\"],[\"experiment\",\"@exp_type\"],[\"layer\",\"@layer_num\"],[\"score\",\"@score{0.0%} (\\u0394 @delta_score{0.0%})\"],[\"headroom fraction\",\"@headroom_frac{0.0%}\"]]},\"id\":\"7213\",\"type\":\"HoverTool\"},{\"attributes\":{\"plot\":{\"id\":\"7215\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"source\":{\"id\":\"7282\",\"type\":\"ColumnDataSource\"},\"text\":{\"field\":\"_formatted_kl_unif\"},\"text_color\":{\"value\":\"#404040\"},\"text_font_size\":{\"value\":\"12pt\"},\"x\":{\"value\":0.5},\"y\":{\"field\":\"_display_name\"},\"y_offset\":{\"value\":18}},\"id\":\"7283\",\"type\":\"LabelSet\"},{\"attributes\":{\"plot\":{\"id\":\"7215\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"source\":{\"id\":\"7279\",\"type\":\"ColumnDataSource\"},\"text\":{\"field\":\"_formatted_kl_unif\"},\"text_align\":\"right\",\"text_color\":{\"value\":\"#404040\"},\"text_font_size\":{\"value\":\"12pt\"},\"x\":{\"value\":2.5},\"x_offset\":{\"value\":-10},\"y\":{\"field\":\"_display_name\"},\"y_offset\":{\"value\":18}},\"id\":\"7280\",\"type\":\"LabelSet\"},{\"attributes\":{\"callback\":null,\"data\":{\"_bar_center\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"_bar_height\":[],\"_display_name\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"_fill_color\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"_formatted_exp_layer\":[],\"_formatted_kl_unif\":[],\"_line_color\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"accuracy\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"accuracy_errn95\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"contextual_headroom\":[],\"delta_score\":[],\"display_col\":[],\"display_row\":[],\"exp_layer\":[],\"exp_name\":[],\"exp_type\":[],\"f1_errn95\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"f1_score\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"fn_count\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"fp_count\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"headroom_frac\":[],\"index\":[],\"kl_unif\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"label\":[],\"layer_num\":[],\"lex_score\":[],\"max_layer_score\":[],\"num_epochs\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"num_steps\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"precision\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"precision_errn95\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"pred_pos_count\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"prev_layer_score\":[],\"prev_score_max\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"real_delta_score\":[],\"real_headroom_frac\":[],\"recall\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"recall_errn95\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"run\":[],\"score\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"score_errn95\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"seed\":[],\"split\":[],\"stratifier\":[],\"stratum_key\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"tag\":[],\"task\":[],\"tn_count\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"total_count\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"tp_count\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"true_pos_count\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]}},\"selected\":{\"id\":\"7586\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"7587\",\"type\":\"UnionRenderers\"}},\"id\":\"7264\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"callback\":null,\"data\":{\"_bar_center\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"_bar_height\":[],\"_display_name\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"_fill_color\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"_formatted_exp_layer\":[],\"_formatted_kl_unif\":[],\"_line_color\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"accuracy\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"accuracy_errn95\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"contextual_headroom\":[],\"delta_score\":[],\"display_col\":[],\"display_row\":[],\"exp_layer\":[],\"exp_name\":[],\"exp_type\":[],\"f1_errn95\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"f1_score\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"fn_count\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"fp_count\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"headroom_frac\":[],\"index\":[],\"kl_unif\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"label\":[],\"layer_num\":[],\"lex_score\":[],\"max_layer_score\":[],\"num_epochs\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"num_steps\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"precision\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"precision_errn95\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"pred_pos_count\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"prev_layer_score\":[],\"prev_score_max\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"real_delta_score\":[],\"real_headroom_frac\":[],\"recall\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"recall_errn95\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"run\":[],\"score\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"score_errn95\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"seed\":[],\"split\":[],\"stratifier\":[],\"stratum_key\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"tag\":[],\"task\":[],\"tn_count\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"total_count\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"tp_count\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]},\"true_pos_count\":{\"__ndarray__\":\"\",\"dtype\":\"float64\",\"shape\":[0]}},\"selected\":{\"id\":\"7592\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"7593\",\"type\":\"UnionRenderers\"}},\"id\":\"7282\",\"type\":\"ColumnDataSource\"},{\"attributes\":{},\"id\":\"7581\",\"type\":\"UnionRenderers\"},{\"attributes\":{},\"id\":\"7580\",\"type\":\"Selection\"},{\"attributes\":{\"range\":{\"id\":\"7214\",\"type\":\"FactorRange\"}},\"id\":\"7249\",\"type\":\"Dodge\"},{\"attributes\":{\"callback\":null,\"renderers\":[{\"id\":\"7255\",\"type\":\"GlyphRenderer\"},{\"id\":\"7261\",\"type\":\"GlyphRenderer\"}],\"tooltips\":[[\"task\",\"@_display_name\"],[\"experiment\",\"@exp_type\"],[\"layer\",\"@layer_num\"],[\"weight\",\"@layer_weight{0.0%}\"]]},\"id\":\"7212\",\"type\":\"HoverTool\"},{\"attributes\":{},\"id\":\"7579\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"formatter\":{\"id\":\"7577\",\"type\":\"BasicTickFormatter\"},\"major_label_text_font_size\":{\"value\":\"13pt\"},\"plot\":{\"id\":\"7215\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"ticker\":{\"id\":\"7277\",\"type\":\"FixedTicker\"}},\"id\":\"7223\",\"type\":\"LinearAxis\"},{\"attributes\":{\"source\":{\"id\":\"7243\",\"type\":\"ColumnDataSource\"}},\"id\":\"7248\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.0},\"fill_color\":{\"value\":\"#1f77b4\"},\"height\":{\"units\":\"data\",\"value\":0.5},\"line_alpha\":{\"value\":0.0},\"line_color\":{\"value\":\"#1f77b4\"},\"width\":{\"units\":\"data\",\"value\":0.9},\"x\":{\"field\":\"layer_num\"},\"y\":{\"field\":\"_bar_center\",\"transform\":{\"id\":\"7249\",\"type\":\"Dodge\"}}},\"id\":\"7259\",\"type\":\"Rect\"},{\"attributes\":{},\"id\":\"7587\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"range\":{\"id\":\"7214\",\"type\":\"FactorRange\"}},\"id\":\"7263\",\"type\":\"Dodge\"},{\"attributes\":{},\"id\":\"7578\",\"type\":\"Selection\"},{\"attributes\":{\"data_source\":{\"id\":\"7243\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"7245\",\"type\":\"HBar\"},\"hover_glyph\":null,\"level\":\"underlay\",\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"7246\",\"type\":\"HBar\"},\"selection_glyph\":null,\"view\":{\"id\":\"7248\",\"type\":\"CDSView\"}},\"id\":\"7247\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"source\":{\"id\":\"7257\",\"type\":\"ColumnDataSource\"}},\"id\":\"7262\",\"type\":\"CDSView\"},{\"attributes\":{\"callback\":null,\"data\":{\"_bar_center\":[\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\"],\"_bar_height\":[0.31732210516929626,0.07503759860992432,0.2977501153945923,0.08463462442159653,0.3475206792354584,0.3087686002254486,0.15112213790416718,0.2875621020793915],\"_display_name\":[\"Coref.\",\"Deps.\",\"Entities\",\"Consts.\",\"POS\",\"SPR\",\"SRL\",\"Relations\"],\"_formatted_entropy\":[\"H(s) = 1.49 bits\",\"H(s) = 0.76 bits\",\"H(s) = 1.55 bits\",\"H(s) = 0.81 bits\",\"H(s) = 1.45 bits\",\"H(s) = 1.58 bits\",\"H(s) = 1.11 bits\",\"H(s) = 1.58 bits\"],\"_formatted_kl_unif\":[\"K(s) = 0.10\",\"K(s) = 0.82\",\"K(s) = 0.04\",\"K(s) = 0.77\",\"K(s) = 0.14\",\"K(s) = 0.00\",\"K(s) = 0.48\",\"K(s) = 0.01\"],\"checkpoint\":[\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\",\"/model_state_eval_best.th\"],\"display_col\":[\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\",\"elmo-full (base)\"],\"exp_name\":[\"elmo-full-edges-coref-ontonotes-conll\",\"elmo-full-edges-dep-labeling-ewt\",\"elmo-full-edges-ner-ontonotes\",\"elmo-full-edges-nonterminal-ontonotes\",\"elmo-full-edges-pos-ontonotes\",\"elmo-full-edges-spr1\",\"elmo-full-edges-srl-conll2012\",\"elmo-full-edges-rel-semeval\"],\"exp_type\":[\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\",\"elmo-full\"],\"gamma\":{\"__ndarray__\":\"AAAAICDCAED/////Lt0JQAAAAMAFeAJAAAAA4O5cAkAAAADAW5voPwAAAABIkvA/AAAAoMuEAEAAAAAAMxnxPw==\",\"dtype\":\"float64\",\"shape\":[8]},\"index\":[0,1,2,3,4,5,6,7],\"label\":[\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\",\"NaN\"],\"layer_num\":[0,0,0,0,0,0,0,0],\"layer_weight\":[0.31732210516929626,0.07503759860992432,0.2977501153945923,0.08463462442159653,0.3475206792354584,0.3087686002254486,0.15112213790416718,0.2875621020793915],\"run\":[\"elmo-full-edges-coref-ontonotes-conll/run\",\"elmo-full-edges-dep-labeling-ewt/run\",\"elmo-full-edges-ner-ontonotes/run\",\"elmo-full-edges-nonterminal-ontonotes/run\",\"elmo-full-edges-pos-ontonotes/run\",\"elmo-full-edges-spr1/run\",\"elmo-full-edges-srl-conll2012/run\",\"/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run\"],\"scalar_set\":[\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\",\"sent_encoder._text_field_embedder.token_embedder_elmo._elmo.scalar_mix_1.\"],\"tag\":[\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\",\"base\"],\"task\":[\"coref-ontonotes-conll\",\"dep-labeling-ewt\",\"ner-ontonotes\",\"nonterminal-ontonotes\",\"pos-ontonotes\",\"spr1\",\"srl-conll2012\",\"rel-semeval\"],\"weight_entropy\":[1.4852019289109135,0.763671074960612,1.5490914199146366,0.8148412450544743,1.4478285510345674,1.5815782547320176,1.1097871917179196,1.577988976808511],\"weight_exp_layer\":{\"__ndarray__\":\"AAAA4PL06z8AAAB8LwTwPwAAADCt6e4/AAAAqDvm7z8AAADQdNbpPwAAABDuS/A/AAAASFL77j8AAAAY6hjxPw==\",\"dtype\":\"float64\",\"shape\":[8]},\"weight_exp_layer_oneplus\":{\"__ndarray__\":\"O9rh39F59D+M1ZY80FDxPzMc3xyEAvY/cfUrH6Rs8T/uGL6ytczzP4UiQhyBk/c/T0HUjaY/8j+oZuXSkv/3Pw==\",\"dtype\":\"float64\",\"shape\":[8]},\"weight_kl_unif\":{\"__ndarray__\":\"zYnp3eiJuT+ILOEcBUjqP3rt0nOxXaI/+HX9RtWk6D/tXl6Tmo3BP+8H2W1puWs/Xc9di0Vp3j/ge2yqK5B8Pw==\",\"dtype\":\"float64\",\"shape\":[8]}},\"selected\":{\"id\":\"7590\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"7591\",\"type\":\"UnionRenderers\"}},\"id\":\"7279\",\"type\":\"ColumnDataSource\"},{\"attributes\":{},\"id\":\"7586\",\"type\":\"Selection\"},{\"attributes\":{\"data_source\":{\"id\":\"7237\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"7239\",\"type\":\"HBar\"},\"hover_glyph\":null,\"level\":\"image\",\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"7240\",\"type\":\"HBar\"},\"selection_glyph\":null,\"view\":{\"id\":\"7242\",\"type\":\"CDSView\"}},\"id\":\"7241\",\"type\":\"GlyphRenderer\"},{\"attributes\":{},\"id\":\"7577\",\"type\":\"BasicTickFormatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"height\":{\"value\":1.0},\"left\":{\"value\":-0.5},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"line_width\":{\"value\":0.5},\"right\":{\"value\":2.5},\"y\":{\"field\":\"_display_name\"}},\"id\":\"7246\",\"type\":\"HBar\"},{\"attributes\":{\"data_source\":{\"id\":\"7257\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"7259\",\"type\":\"Rect\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"7260\",\"type\":\"Rect\"},\"selection_glyph\":null,\"view\":{\"id\":\"7262\",\"type\":\"CDSView\"}},\"id\":\"7261\",\"type\":\"GlyphRenderer\"},{\"attributes\":{},\"id\":\"7585\",\"type\":\"UnionRenderers\"},{\"attributes\":{},\"id\":\"7575\",\"type\":\"CategoricalTickFormatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.0},\"fill_color\":{\"value\":\"White\"},\"height\":{\"value\":1.0},\"left\":{\"value\":-0.5},\"line_color\":{\"value\":\"#e6e6e6\"},\"line_width\":{\"value\":0.5},\"right\":{\"value\":2.5},\"y\":{\"field\":\"_display_name\"}},\"id\":\"7245\",\"type\":\"HBar\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"height\":{\"value\":1.0},\"left\":{\"value\":-0.5},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"right\":{\"value\":2.5},\"y\":{\"field\":\"_display_name\"}},\"id\":\"7240\",\"type\":\"HBar\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"height\":{\"units\":\"data\",\"value\":0.5},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"width\":{\"units\":\"data\",\"value\":0.9},\"x\":{\"field\":\"layer_num\"},\"y\":{\"field\":\"_bar_center\",\"transform\":{\"id\":\"7249\",\"type\":\"Dodge\"}}},\"id\":\"7260\",\"type\":\"Rect\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"height\":{\"field\":\"_bar_height\",\"units\":\"data\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"line_width\":{\"value\":1.5},\"width\":{\"units\":\"data\",\"value\":0.9},\"x\":{\"field\":\"layer_num\"},\"y\":{\"field\":\"_bar_center\",\"transform\":{\"id\":\"7263\",\"type\":\"Dodge\"}}},\"id\":\"7267\",\"type\":\"Rect\"},{\"attributes\":{},\"id\":\"7584\",\"type\":\"Selection\"},{\"attributes\":{\"plot\":null,\"text\":\"\"},\"id\":\"7574\",\"type\":\"Title\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.4},\"fill_color\":{\"value\":\"#f2f2f2\"},\"height\":{\"value\":1.0},\"left\":{\"value\":-0.5},\"line_alpha\":{\"value\":0.0},\"line_color\":{\"value\":\"#1f77b4\"},\"right\":{\"value\":2.5},\"y\":{\"field\":\"_display_name\"}},\"id\":\"7239\",\"type\":\"HBar\"},{\"attributes\":{},\"id\":\"7583\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.0},\"fill_color\":{\"value\":\"#1f77b4\"},\"height\":{\"units\":\"data\",\"value\":0.5},\"line_alpha\":{\"value\":0.0},\"line_color\":{\"value\":\"#1f77b4\"},\"width\":{\"units\":\"data\",\"value\":0.9},\"x\":{\"field\":\"layer_num\"},\"y\":{\"field\":\"_bar_center\",\"transform\":{\"id\":\"7263\",\"type\":\"Dodge\"}}},\"id\":\"7273\",\"type\":\"Rect\"},{\"attributes\":{},\"id\":\"7232\",\"type\":\"SaveTool\"}],\"root_ids\":[\"7215\"]},\"title\":\"Bokeh Application\",\"version\":\"1.0.4\"}};\n", - " var render_items = [{\"docid\":\"91e6a285-ac1b-48da-afcd-150f6ad88247\",\"roots\":{\"7215\":\"f70fac40-e911-43d7-a62e-f7ecd3ec9507\"}}];\n", - " root.Bokeh.embed.embed_items_notebook(docs_json, render_items);\n", - "\n", - " }\n", - " if (root.Bokeh !== undefined) {\n", - " embed_document(root);\n", - " } else {\n", - " var attempts = 0;\n", - " var timer = setInterval(function(root) {\n", - " if (root.Bokeh !== undefined) {\n", - " embed_document(root);\n", - " clearInterval(timer);\n", - " }\n", - " attempts++;\n", - " if (attempts > 100) {\n", - " console.log(\"Bokeh: ERROR: Unable to run BokehJS code because BokehJS library is missing\");\n", - " clearInterval(timer);\n", - " }\n", - " }, 10, root)\n", - " }\n", - "})(window);" - ], - "application/vnd.bokehjs_exec.v0+json": "" - }, - "metadata": { - "application/vnd.bokehjs_exec.v0+json": { - "id": "7215" - } - }, - "output_type": "display_data" - } - ], - "source": [ - "# https://bokeh.pydata.org/en/latest/docs/reference/palettes.html\n", - "palette = bokeh.palettes.Category20c_20\n", - "\n", - "# MODEL_NAME = \"bert-base-uncased\"\n", - "# MODEL_NAME = \"bert-large-uncased\"\n", - "# EXPT_TYPES = [f\"{MODEL_NAME}-mix\"]\n", - "MODEL_NAME = \"elmo-full\"\n", - "EXPT_TYPES = [\"elmo-full\"]\n", - "MAX_LAYER = 2\n", - "WEIGHT_SCALE = 1.0\n", - "# SCORE_EXPT_TYPE = f\"{MODEL_NAME}-mix\"\n", - "# MAX_LAYER = 24 if '-large-' in MODEL_NAME else 12\n", - "# WEIGHT_SCALE = 2.7 if '-large-' in MODEL_NAME else 2.1\n", - "# SCORE_SCALE = 1.5\n", - "# SCORE_SCALE = 2.2\n", - "SCORE_SCALE = WEIGHT_SCALE\n", - "WEIGHT_COLORS = (palette[0], palette[9]) # blue, green\n", - "SCORE_COLORS = (palette[12], palette[12]) # purples\n", - "NEG_COLORS = (palette[5], palette[4]) # oranges\n", - "# PLOT_WIDTH = 900\n", - "# PLOT_WIDTH=450\n", - "PLOT_WIDTH=200\n", - "# _PLOT_HEIGHT_FN=lambda num_cats: 80 + 100*num_cats\n", - "_PLOT_HEIGHT_FN=lambda num_cats: 750\n", - "\n", - "##\n", - "# Don't change below here\n", - "##\n", - "def _make_display_name(task, label):\n", - " if task.startswith(\"pos-\"):\n", - " return \"POS\"\n", - " elif task.startswith(\"coref-\"):\n", - " return \"Coref.\"\n", - " elif task.startswith(\"spr\"):\n", - " return \"SPR\"\n", - " elif task.startswith(\"rel-\"):\n", - " return \"Relations\"\n", - " elif task.startswith(\"dep-\"):\n", - " return \"Deps.\"\n", - " elif task.startswith(\"nonterminal-\"):\n", - " return \"Consts.\"\n", - " else:\n", - " return analysis.make_display_name(task, label) \n", - "\n", - "def _make_mask(df):\n", - " mask = df['exp_type'].map(lambda s: s in EXPT_TYPES)\n", - " mask &= df['task'] != 'constituent-ontonotes' # don't use this task\n", - " mask &= df['task'] != 'ner-tacred' # don't use this task\n", - " mask &= df['task'] != 'coref-gap-ontonotes' # don't use this task\n", - " mask &= df['task'] != 'rel-tacred' # don't use this task\n", - "# mask &= df['task'] != 'rel-semeval' # don't use this task\n", - " # Skip Winograd and SPR2 for this\n", - " mask &= df['task'] != 'dpr'\n", - "# mask &= df['task'] != 'spr1'\n", - " mask &= df['task'] != 'spr2'\n", - " return mask\n", - "\n", - "mask = _make_mask(scalar_df)\n", - "weight_df = scalar_df[mask].copy()\n", - "\n", - "##\n", - "# Make long-form DataFrame and add plotting values\n", - "skip_cols = set(scalar_columns.keys()).union(scalar_columns.values())\n", - "id_vars = [c for c in weight_df.columns if c not in skip_cols]\n", - "value_vars = scalar_columns.keys()\n", - "weight_df = pd.melt(weight_df, id_vars=id_vars, value_vars=value_vars, \n", - " var_name=\"layer_num\", value_name=\"layer_weight\")\n", - "weight_df['label'] = None\n", - "\n", - "##\n", - "# Append the scores DataFrame\n", - "mask = _make_mask(fdf)\n", - "mask &= fdf['layer_num'].notnull()\n", - "mask &= fdf['exp_type'] == SCORE_EXPT_TYPE\n", - "# mask &= fdf['layer_num'].astype(float) > 0\n", - "score_df = fdf[mask].copy()\n", - "# Erase labels, for now\n", - "score_df['label'] = None\n", - "\n", - "##\n", - "# Plotting code below this line\n", - "##\n", - "\n", - "# Row keys\n", - "sorted_tasks = sorted(weight_df['task'].unique(), key=task_sort_key)\n", - "cats = [_make_display_name(t, None) for t in sorted_tasks]\n", - "cats = list(reversed(cats))\n", - "PLOT_HEIGHT = _PLOT_HEIGHT_FN(len(cats))\n", - "\n", - "# Row names, matching row keys\n", - "score_df['_display_name'] = list(map(_make_display_name, score_df['task'], score_df['label']))\n", - "weight_df['_display_name'] = list(map(_make_display_name, weight_df['task'], weight_df['label']))\n", - "\n", - "# Bar heights for weights\n", - "weight_df['_bar_height'] = weight_df['layer_weight'] * WEIGHT_SCALE\n", - "weight_df['_bar_center'] = weight_df['_display_name']\n", - "weight_df['_formatted_entropy'] = weight_df['weight_entropy'].map(lambda h: \"H(s) = {:.02f} bits\".format(h))\n", - "# weight_df['_formatted_kl_unif'] = weight_df['weight_kl_unif'].map(lambda h: \"KL(s||uniform) = {:.02f} bits\".format(h))\n", - "weight_df['_formatted_kl_unif'] = weight_df['weight_kl_unif'].map(lambda h: \"K(s) = {:.02f}\".format(h))\n", - "# weight_df['_formatted_exp_layer'] = weight_df['weight_exp_layer_oneplus'].map(lambda l: \"E[k] = {:.02f}\".format(l))\n", - "\n", - "# Bar heights for scores (cumulative)\n", - "# score_df['_bar_height'] = score_df['real_headroom_frac'] * SCORE_SCALE\n", - "score_df['_bar_height'] = score_df['headroom_frac'] * SCORE_SCALE\n", - "score_df['_bar_height'] = score_df['_bar_height'].map(lambda h: min(h, 1.0))\n", - "# Add offset so bars start at baseline\n", - "score_df['_bar_center'] = [(l, h/2-0.5) for l, h in zip(score_df['_display_name'], score_df['_bar_height'])]\n", - "# score_df['_bar_center'] = score_df[\"_display_name\"]\n", - "\n", - "score_df['_fill_color'] = [SCORE_COLORS[0] if h > 0 else NEG_COLORS[0] for h in score_df['_bar_height']]\n", - "score_df['_line_color'] = [SCORE_COLORS[1] if h > 0 else NEG_COLORS[1] for h in score_df['_bar_height']]\n", - "score_df['_bar_height'] = score_df['_bar_height'].map(np.abs)\n", - "\n", - "# score_df['_formatted_exp_layer'] = score_df['exp_layer'].map(lambda l: \"E[layer] = {:.02f}\".format(l))\n", - "score_df['_formatted_exp_layer'] = score_df['exp_layer'].map(lambda l: \"{:.02f}\".format(l))\n", - "score_df['_formatted_kl_unif'] = score_df['kl_unif'].map(lambda h: \"K(Δ) = {:.02f}\".format(h))\n", - "\n", - "hover_0 = bokeh.models.HoverTool(\n", - " tooltips=[\n", - " (\"task\", \"@_display_name\"),\n", - " (\"experiment\", \"@exp_type\"),\n", - " (\"layer\", \"@layer_num\"),\n", - " (\"weight\", \"@layer_weight{0.0%}\"),\n", - " ],\n", - " renderers=[],\n", - ")\n", - "hover_2 = bokeh.models.HoverTool(\n", - " tooltips=[\n", - " (\"task\", \"@_display_name\"),\n", - " (\"experiment\", \"@exp_type\"),\n", - " (\"layer\", \"@layer_num\"),\n", - " (\"score\", \"@score{0.0%} (Δ @delta_score{0.0%})\"),\n", - " (\"headroom fraction\", \"@headroom_frac{0.0%}\"),\n", - " ],\n", - " renderers=[],\n", - ")\n", - "\n", - "x_range = (-0.5, MAX_LAYER+0.5)\n", - "p = bp.figure(y_range=bokeh.models.FactorRange(*cats, factor_padding=0.10), x_range=x_range,\n", - " plot_width=PLOT_WIDTH, plot_height=PLOT_HEIGHT, tools=[hover_0, hover_2, 'save'])\n", - "\n", - "##\n", - "# Add background bars\n", - "bgbar_color = \"#f2f2f2\"\n", - "p.hbar(y='_display_name', left=x_range[0], right=x_range[1], \n", - " height=1.0, \n", - " fill_color=bgbar_color, fill_alpha=0.40, \n", - "# line_color=\"#e6e6e6\", \n", - "# line_alpha=0.80,\n", - "# line_color=\"Gray\",\n", - " line_alpha=0.0,\n", - "# line_width=0.5,\n", - " source=weight_df, \n", - " level='image')\n", - "p.hbar(y='_display_name', left=x_range[0], right=x_range[1], \n", - " height=1.0, \n", - " fill_color=\"White\", fill_alpha=0.0,\n", - " line_color=\"#e6e6e6\",\n", - " line_alpha=1.0,\n", - " line_width=0.5,\n", - " source=weight_df, \n", - " level='underlay')\n", - "\n", - "def _plot_bars(sdf, x_dodge=0, y_dodge=0, **kw):\n", - " y = bokeh.transform.dodge('_bar_center', y_dodge, range=p.y_range)\n", - " x = 'layer_num'\n", - " bars = p.rect(x=x, y=y, width=0.9, height=\"_bar_height\", source=sdf, **kw)\n", - " shadow_bars = p.rect(x=x, y=y, width=0.9, height=0.5, source=sdf, alpha=0.0)\n", - " return bars, shadow_bars\n", - "\n", - "##\n", - "# Plot weights and delta scores\n", - "_WEIGHT_BAR_PARAMS = dict(fill_color=WEIGHT_COLORS[0], line_color=WEIGHT_COLORS[0],\n", - "# line_width=1.5, fill_alpha=0.1,\n", - " )\n", - "_SCORE_BAR_PARAMS = dict(fill_color='_fill_color', line_color='_line_color', \n", - " line_width=1.5, fill_alpha=0.1,\n", - " )\n", - "b0, s0 = _plot_bars(weight_df[weight_df.exp_type == EXPT_TYPES[0]], y_dodge=0, \n", - " hover_fill_color=\"firebrick\", hover_fill_alpha=1.0,\n", - " **_WEIGHT_BAR_PARAMS)\n", - "b2, s2 = _plot_bars(score_df[score_df['layer_num'].map(int) > 0], y_dodge=0, \n", - " hover_fill_color=\"firebrick\", hover_fill_alpha=0.7, **_SCORE_BAR_PARAMS)\n", - "hover_0.renderers.extend([b0, s0])\n", - "hover_2.renderers.extend([b2, s2])\n", - "\n", - "p.xaxis.ticker = bokeh.models.FixedTicker(ticks=np.arange(0, MAX_LAYER+1))\n", - "p.xgrid.ticker = p.xaxis[0].ticker\n", - " \n", - "_FONT_SIZE = \"13pt\"\n", - "p.yaxis.major_label_text_font_size = _FONT_SIZE\n", - "p.xaxis.major_label_text_font_size = _FONT_SIZE\n", - "# p.xaxis.axis_label = \"Encoder Layer\"\n", - "# p.xaxis.axis_label_text_font_size = _FONT_SIZE\n", - "\n", - "# p.yaxis.major_label_orientation = 60 * np.pi / 180\n", - "p.yaxis.major_label_orientation = \"vertical\"\n", - "if PLOT_WIDTH < 600 and MAX_LAYER > 12:\n", - " p.xaxis.ticker = bokeh.models.FixedTicker(ticks=np.arange(0, MAX_LAYER+1, 2))\n", - "\n", - "# p.toolbar.autohide = True\n", - "\n", - "# Add labels with entropy\n", - "# _label_y = [28, 10]\n", - "label_kw = [\n", - " dict(x=x_range[1], y_offset=18, x_offset=-10, text_baseline=\"bottom\", text_align=\"right\"),\n", - " dict(x=x_range[1]*0.20, y_offset=18, x_offset=0, text_baseline=\"bottom\", text_align=\"left\"),\n", - "]\n", - "LABEL_COLOR = \"#404040\"\n", - "score_labels = bokeh.models.annotations.LabelSet(\n", - " y=\"_display_name\", text=\"_formatted_kl_unif\",\n", - " text_color=LABEL_COLOR, text_font_size=\"12pt\",\n", - " source=bokeh.models.ColumnDataSource(weight_df[weight_df['layer_num'] == 0]), **label_kw[0])\n", - "p.add_layout(score_labels)\n", - "score_labels = bokeh.models.annotations.LabelSet(\n", - " y=\"_display_name\", text=\"_formatted_kl_unif\",\n", - " text_color=LABEL_COLOR, text_font_size=\"12pt\",\n", - " source=bokeh.models.ColumnDataSource(score_df[score_df['layer_num'].map(int) == 0]), **label_kw[1])\n", - "p.add_layout(score_labels)\n", - "# # Add labels with expected layer\n", - "# score_labels = bokeh.models.annotations.LabelSet(\n", - "# y=\"_display_name\", \n", - "# # x=\"weight_exp_layer\",\n", - "# x=x_range[1] // 6, \n", - "# text=\"_formatted_exp_layer\",\n", - "# text_align=\"left\", text_baseline=\"bottom\", y_offset=25, x_offset=0,\n", - "# text_color=\"#595959\", text_font_size=\"11pt\",\n", - "# source=bokeh.models.ColumnDataSource(weight_df[weight_df['layer_num'] == 0]))\n", - "# p.add_layout(score_labels)\n", - "\n", - "# p.xgrid.visible = False\n", - "p.min_border_left = 0\n", - "p.min_border_right = 0\n", - "p.min_border_top = 0\n", - "p.min_border_bottom = 0\n", - "p.toolbar_location = None\n", - "\n", - "bp.show(p)" - ] - }, - { - "cell_type": "code", - "execution_count": 51, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Copying file:///tmp/elmo-full.weights.20190603.212822.html [Content-Type=text/html]...\n", - "/ [1 files][315.4 KiB/315.4 KiB] \n", - "Operation completed over 1 objects/315.4 KiB. \n", - "Updated ACL on gs://edge-probing/iftenney/plots/elmo-full.weights.20190603.212822.html\n", - "Public URL: https://storage.googleapis.com/edge-probing/iftenney/plots/elmo-full.weights.20190603.212822.html\n" - ] - }, - { - "data": { - "text/plain": [ - "'https://storage.googleapis.com/edge-probing/iftenney/plots/elmo-full.weights.20190603.212822.html'" - ] - }, - "execution_count": 51, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "_save_figure_to_bucket(p, name=f\"{MODEL_NAME}.weights\",\n", - " title=f\"{MODEL_NAME} mixing weights\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "jiant", - "language": "python", - "name": "jiant" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.6.8" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/probing/analysis_edgeprobe_ICLR_camera_ready.ipynb b/probing/analysis_edgeprobe_ICLR_camera_ready.ipynb deleted file mode 100644 index a9dbad104..000000000 --- a/probing/analysis_edgeprobe_ICLR_camera_ready.ipynb +++ /dev/null @@ -1,4329 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Edgeprobe Aggregate Analysis (for ICLR camera-ready)\n", - "\n", - "This is the main analysis notebook for [What do you learn from context? Probing for sentence structure in contextualized word representations](https://openreview.net/forum?id=SJzSgnRcKX), a.k.a. \"the edge probing paper.\"\n", - "\n", - "This notebook is intended to be run on the output of the [`analyze_runs.py`](analyze_runs.py) script; run that on a folder of experiments to produce a `scores.tsv` file that can be loaded here." - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "import sys, os, re, json\n", - "from importlib import reload\n", - "import itertools\n", - "import collections\n", - "\n", - "import numpy as np\n", - "import pandas as pd" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - "
\n", - " \n", - " Loading BokehJS ...\n", - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": [ - "\n", - "(function(root) {\n", - " function now() {\n", - " return new Date();\n", - " }\n", - "\n", - " var force = true;\n", - "\n", - " if (typeof (root._bokeh_onload_callbacks) === \"undefined\" || force === true) {\n", - " root._bokeh_onload_callbacks = [];\n", - " root._bokeh_is_loading = undefined;\n", - " }\n", - "\n", - " var JS_MIME_TYPE = 'application/javascript';\n", - " var HTML_MIME_TYPE = 'text/html';\n", - " var EXEC_MIME_TYPE = 'application/vnd.bokehjs_exec.v0+json';\n", - " var CLASS_NAME = 'output_bokeh rendered_html';\n", - "\n", - " /**\n", - " * Render data to the DOM node\n", - " */\n", - " function render(props, node) {\n", - " var script = document.createElement(\"script\");\n", - " node.appendChild(script);\n", - " }\n", - "\n", - " /**\n", - " * Handle when an output is cleared or removed\n", - " */\n", - " function handleClearOutput(event, handle) {\n", - " var cell = handle.cell;\n", - "\n", - " var id = cell.output_area._bokeh_element_id;\n", - " var server_id = cell.output_area._bokeh_server_id;\n", - " // Clean up Bokeh references\n", - " if (id != null && id in Bokeh.index) {\n", - " Bokeh.index[id].model.document.clear();\n", - " delete Bokeh.index[id];\n", - " }\n", - "\n", - " if (server_id !== undefined) {\n", - " // Clean up Bokeh references\n", - " var cmd = \"from bokeh.io.state import curstate; print(curstate().uuid_to_server['\" + server_id + \"'].get_sessions()[0].document.roots[0]._id)\";\n", - " cell.notebook.kernel.execute(cmd, {\n", - " iopub: {\n", - " output: function(msg) {\n", - " var id = msg.content.text.trim();\n", - " if (id in Bokeh.index) {\n", - " Bokeh.index[id].model.document.clear();\n", - " delete Bokeh.index[id];\n", - " }\n", - " }\n", - " }\n", - " });\n", - " // Destroy server and session\n", - " var cmd = \"import bokeh.io.notebook as ion; ion.destroy_server('\" + server_id + \"')\";\n", - " cell.notebook.kernel.execute(cmd);\n", - " }\n", - " }\n", - "\n", - " /**\n", - " * Handle when a new output is added\n", - " */\n", - " function handleAddOutput(event, handle) {\n", - " var output_area = handle.output_area;\n", - " var output = handle.output;\n", - "\n", - " // limit handleAddOutput to display_data with EXEC_MIME_TYPE content only\n", - " if ((output.output_type != \"display_data\") || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n", - " return\n", - " }\n", - "\n", - " var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n", - "\n", - " if (output.metadata[EXEC_MIME_TYPE][\"id\"] !== undefined) {\n", - " toinsert[toinsert.length - 1].firstChild.textContent = output.data[JS_MIME_TYPE];\n", - " // store reference to embed id on output_area\n", - " output_area._bokeh_element_id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n", - " }\n", - " if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n", - " var bk_div = document.createElement(\"div\");\n", - " bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n", - " var script_attrs = bk_div.children[0].attributes;\n", - " for (var i = 0; i < script_attrs.length; i++) {\n", - " toinsert[toinsert.length - 1].firstChild.setAttribute(script_attrs[i].name, script_attrs[i].value);\n", - " }\n", - " // store reference to server id on output_area\n", - " output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n", - " }\n", - " }\n", - "\n", - " function register_renderer(events, OutputArea) {\n", - "\n", - " function append_mime(data, metadata, element) {\n", - " // create a DOM node to render to\n", - " var toinsert = this.create_output_subarea(\n", - " metadata,\n", - " CLASS_NAME,\n", - " EXEC_MIME_TYPE\n", - " );\n", - " this.keyboard_manager.register_events(toinsert);\n", - " // Render to node\n", - " var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n", - " render(props, toinsert[toinsert.length - 1]);\n", - " element.append(toinsert);\n", - " return toinsert\n", - " }\n", - "\n", - " /* Handle when an output is cleared or removed */\n", - " events.on('clear_output.CodeCell', handleClearOutput);\n", - " events.on('delete.Cell', handleClearOutput);\n", - "\n", - " /* Handle when a new output is added */\n", - " events.on('output_added.OutputArea', handleAddOutput);\n", - "\n", - " /**\n", - " * Register the mime type and append_mime function with output_area\n", - " */\n", - " OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n", - " /* Is output safe? */\n", - " safe: true,\n", - " /* Index of renderer in `output_area.display_order` */\n", - " index: 0\n", - " });\n", - " }\n", - "\n", - " // register the mime type if in Jupyter Notebook environment and previously unregistered\n", - " if (root.Jupyter !== undefined) {\n", - " var events = require('base/js/events');\n", - " var OutputArea = require('notebook/js/outputarea').OutputArea;\n", - "\n", - " if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n", - " register_renderer(events, OutputArea);\n", - " }\n", - " }\n", - "\n", - " \n", - " if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n", - " root._bokeh_timeout = Date.now() + 5000;\n", - " root._bokeh_failed_load = false;\n", - " }\n", - "\n", - " var NB_LOAD_WARNING = {'data': {'text/html':\n", - " \"
\\n\"+\n", - " \"

\\n\"+\n", - " \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n", - " \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n", - " \"

\\n\"+\n", - " \"
    \\n\"+\n", - " \"
  • re-rerun `output_notebook()` to attempt to load from CDN again, or
  • \\n\"+\n", - " \"
  • use INLINE resources instead, as so:
  • \\n\"+\n", - " \"
\\n\"+\n", - " \"\\n\"+\n", - " \"from bokeh.resources import INLINE\\n\"+\n", - " \"output_notebook(resources=INLINE)\\n\"+\n", - " \"\\n\"+\n", - " \"
\"}};\n", - "\n", - " function display_loaded() {\n", - " var el = document.getElementById(\"1001\");\n", - " if (el != null) {\n", - " el.textContent = \"BokehJS is loading...\";\n", - " }\n", - " if (root.Bokeh !== undefined) {\n", - " if (el != null) {\n", - " el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n", - " }\n", - " } else if (Date.now() < root._bokeh_timeout) {\n", - " setTimeout(display_loaded, 100)\n", - " }\n", - " }\n", - "\n", - "\n", - " function run_callbacks() {\n", - " try {\n", - " root._bokeh_onload_callbacks.forEach(function(callback) { callback() });\n", - " }\n", - " finally {\n", - " delete root._bokeh_onload_callbacks\n", - " }\n", - " console.info(\"Bokeh: all callbacks have finished\");\n", - " }\n", - "\n", - " function load_libs(js_urls, callback) {\n", - " root._bokeh_onload_callbacks.push(callback);\n", - " if (root._bokeh_is_loading > 0) {\n", - " console.log(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n", - " return null;\n", - " }\n", - " if (js_urls == null || js_urls.length === 0) {\n", - " run_callbacks();\n", - " return null;\n", - " }\n", - " console.log(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n", - " root._bokeh_is_loading = js_urls.length;\n", - " for (var i = 0; i < js_urls.length; i++) {\n", - " var url = js_urls[i];\n", - " var s = document.createElement('script');\n", - " s.src = url;\n", - " s.async = false;\n", - " s.onreadystatechange = s.onload = function() {\n", - " root._bokeh_is_loading--;\n", - " if (root._bokeh_is_loading === 0) {\n", - " console.log(\"Bokeh: all BokehJS libraries loaded\");\n", - " run_callbacks()\n", - " }\n", - " };\n", - " s.onerror = function() {\n", - " console.warn(\"failed to load library \" + url);\n", - " };\n", - " console.log(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", - " document.getElementsByTagName(\"head\")[0].appendChild(s);\n", - " }\n", - " };var element = document.getElementById(\"1001\");\n", - " if (element == null) {\n", - " console.log(\"Bokeh: ERROR: autoload.js configured with elementid '1001' but no matching script tag was found. \")\n", - " return false;\n", - " }\n", - "\n", - " var js_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-1.0.4.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.0.4.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.0.4.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-gl-1.0.4.min.js\"];\n", - "\n", - " var inline_js = [\n", - " function(Bokeh) {\n", - " Bokeh.set_log_level(\"info\");\n", - " },\n", - " \n", - " function(Bokeh) {\n", - " \n", - " },\n", - " function(Bokeh) {\n", - " console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/release/bokeh-1.0.4.min.css\");\n", - " Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/release/bokeh-1.0.4.min.css\");\n", - " console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.0.4.min.css\");\n", - " Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.0.4.min.css\");\n", - " console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/release/bokeh-tables-1.0.4.min.css\");\n", - " Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.0.4.min.css\");\n", - " }\n", - " ];\n", - "\n", - " function run_inline_js() {\n", - " \n", - " if ((root.Bokeh !== undefined) || (force === true)) {\n", - " for (var i = 0; i < inline_js.length; i++) {\n", - " inline_js[i].call(root, root.Bokeh);\n", - " }if (force === true) {\n", - " display_loaded();\n", - " }} else if (Date.now() < root._bokeh_timeout) {\n", - " setTimeout(run_inline_js, 100);\n", - " } else if (!root._bokeh_failed_load) {\n", - " console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n", - " root._bokeh_failed_load = true;\n", - " } else if (force !== true) {\n", - " var cell = $(document.getElementById(\"1001\")).parents('.cell').data().cell;\n", - " cell.output_area.append_execute_result(NB_LOAD_WARNING)\n", - " }\n", - "\n", - " }\n", - "\n", - " if (root._bokeh_is_loading === 0) {\n", - " console.log(\"Bokeh: BokehJS loaded, going straight to plotting\");\n", - " run_inline_js();\n", - " } else {\n", - " load_libs(js_urls, function() {\n", - " console.log(\"Bokeh: BokehJS plotting callback run at\", now());\n", - " run_inline_js();\n", - " });\n", - " }\n", - "}(window));" - ], - "application/vnd.bokehjs_load.v0+json": "\n(function(root) {\n function now() {\n return new Date();\n }\n\n var force = true;\n\n if (typeof (root._bokeh_onload_callbacks) === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\n \n\n \n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n var NB_LOAD_WARNING = {'data': {'text/html':\n \"
\\n\"+\n \"

\\n\"+\n \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n \"

\\n\"+\n \"
    \\n\"+\n \"
  • re-rerun `output_notebook()` to attempt to load from CDN again, or
  • \\n\"+\n \"
  • use INLINE resources instead, as so:
  • \\n\"+\n \"
\\n\"+\n \"\\n\"+\n \"from bokeh.resources import INLINE\\n\"+\n \"output_notebook(resources=INLINE)\\n\"+\n \"\\n\"+\n \"
\"}};\n\n function display_loaded() {\n var el = document.getElementById(\"1001\");\n if (el != null) {\n el.textContent = \"BokehJS is loading...\";\n }\n if (root.Bokeh !== undefined) {\n if (el != null) {\n el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n }\n } else if (Date.now() < root._bokeh_timeout) {\n setTimeout(display_loaded, 100)\n }\n }\n\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) { callback() });\n }\n finally {\n delete root._bokeh_onload_callbacks\n }\n console.info(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(js_urls, callback) {\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.log(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls == null || js_urls.length === 0) {\n run_callbacks();\n return null;\n }\n console.log(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n root._bokeh_is_loading = js_urls.length;\n for (var i = 0; i < js_urls.length; i++) {\n var url = js_urls[i];\n var s = document.createElement('script');\n s.src = url;\n s.async = false;\n s.onreadystatechange = s.onload = function() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.log(\"Bokeh: all BokehJS libraries loaded\");\n run_callbacks()\n }\n };\n s.onerror = function() {\n console.warn(\"failed to load library \" + url);\n };\n console.log(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.getElementsByTagName(\"head\")[0].appendChild(s);\n }\n };var element = document.getElementById(\"1001\");\n if (element == null) {\n console.log(\"Bokeh: ERROR: autoload.js configured with elementid '1001' but no matching script tag was found. \")\n return false;\n }\n\n var js_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-1.0.4.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.0.4.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.0.4.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-gl-1.0.4.min.js\"];\n\n var inline_js = [\n function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\n \n function(Bokeh) {\n \n },\n function(Bokeh) {\n console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/release/bokeh-1.0.4.min.css\");\n Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/release/bokeh-1.0.4.min.css\");\n console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.0.4.min.css\");\n Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.0.4.min.css\");\n console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/release/bokeh-tables-1.0.4.min.css\");\n Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.0.4.min.css\");\n }\n ];\n\n function run_inline_js() {\n \n if ((root.Bokeh !== undefined) || (force === true)) {\n for (var i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }if (force === true) {\n display_loaded();\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n } else if (force !== true) {\n var cell = $(document.getElementById(\"1001\")).parents('.cell').data().cell;\n cell.output_area.append_execute_result(NB_LOAD_WARNING)\n }\n\n }\n\n if (root._bokeh_is_loading === 0) {\n console.log(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(js_urls, function() {\n console.log(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));" - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "import bokeh\n", - "import bokeh.plotting as bp\n", - "bp.output_notebook()" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Better speed can be achieved with apex installed from https://www.github.com/nvidia/apex.\n" - ] - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "import analysis\n", - "reload(analysis)" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": { - "scrolled": true - }, - "outputs": [ - { - "data": { - "text/plain": [ - "OrderedDict([('glove', '#ffbb78'),\n", - " ('glove-cnn1', '#ff7f0e'),\n", - " ('glove-cnn2', '#ff7f0e'),\n", - " ('cove', '#ff9896'),\n", - " ('cove-cnn1', '#d62728'),\n", - " ('cove-cnn2', '#d62728'),\n", - " ('elmo-chars', '#9edae5'),\n", - " ('elmo-chars-cnn1', '#17becf'),\n", - " ('elmo-chars-cnn2', '#17becf'),\n", - " ('elmo-ortho', '#c5b0d5'),\n", - " ('elmo-ortho-cnn1', '#9467bd'),\n", - " ('elmo-ortho-cnn2', '#9467bd'),\n", - " ('elmo-full', '#aec7e8'),\n", - " ('elmo-full-cnn1', '#1f77b4'),\n", - " ('elmo-full-cnn2', '#1f77b4'),\n", - " ('openai-lex', '#dbdb8d'),\n", - " ('openai-lex-cnn1', '#bcbd22'),\n", - " ('openai-lex-cnn2', '#bcbd22'),\n", - " ('openai-cat', '#98df8a'),\n", - " ('openai-cat-cnn1', '#2ca02c'),\n", - " ('openai-cat-cnn2', '#2ca02c'),\n", - " ('openai-mix', '#f7b6d2'),\n", - " ('openai-mix-cnn1', '#e377c2'),\n", - " ('openai-mix-cnn2', '#e377c2'),\n", - " ('openai', '#98df8a'),\n", - " ('openai-cnn1', '#2ca02c'),\n", - " ('openai-cnn2', '#2ca02c'),\n", - " ('openai-bwb', '#f7b6d2'),\n", - " ('openai-bwb-cnn1', '#e377c2'),\n", - " ('openai-bwb-cnn2', '#e377c2'),\n", - " ('train-chars', '#c49c94'),\n", - " ('train-chars-cnn1', '#8c564b'),\n", - " ('train-chars-cnn2', '#8c564b'),\n", - " ('bert-base-uncased-lex', '#dbdb8d'),\n", - " ('bert-base-uncased-lex-cnn1', '#bcbd22'),\n", - " ('bert-base-uncased-lex-cnn2', '#bcbd22'),\n", - " ('bert-base-uncased-cat', '#98df8a'),\n", - " ('bert-base-uncased-cat-cnn1', '#2ca02c'),\n", - " ('bert-base-uncased-cat-cnn2', '#2ca02c'),\n", - " ('bert-base-uncased-mix', '#f7b6d2'),\n", - " ('bert-base-uncased-mix-cnn1', '#e377c2'),\n", - " ('bert-base-uncased-mix-cnn2', '#e377c2'),\n", - " ('bert-base-cased-lex', '#dbdb8d'),\n", - " ('bert-base-cased-lex-cnn1', '#bcbd22'),\n", - " ('bert-base-cased-lex-cnn2', '#bcbd22'),\n", - " ('bert-base-cased-cat', '#98df8a'),\n", - " ('bert-base-cased-cat-cnn1', '#2ca02c'),\n", - " ('bert-base-cased-cat-cnn2', '#2ca02c'),\n", - " ('bert-base-cased-mix', '#f7b6d2'),\n", - " ('bert-base-cased-mix-cnn1', '#e377c2'),\n", - " ('bert-base-cased-mix-cnn2', '#e377c2'),\n", - " ('bert-large-uncased-lex', '#dbdb8d'),\n", - " ('bert-large-uncased-lex-cnn1', '#bcbd22'),\n", - " ('bert-large-uncased-lex-cnn2', '#bcbd22'),\n", - " ('bert-large-uncased-cat', '#98df8a'),\n", - " ('bert-large-uncased-cat-cnn1', '#2ca02c'),\n", - " ('bert-large-uncased-cat-cnn2', '#2ca02c'),\n", - " ('bert-large-uncased-mix', '#f7b6d2'),\n", - " ('bert-large-uncased-mix-cnn1', '#e377c2'),\n", - " ('bert-large-uncased-mix-cnn2', '#e377c2'),\n", - " ('bert-large-cased-lex', '#dbdb8d'),\n", - " ('bert-large-cased-lex-cnn1', '#bcbd22'),\n", - " ('bert-large-cased-lex-cnn2', '#bcbd22'),\n", - " ('bert-large-cased-cat', '#98df8a'),\n", - " ('bert-large-cased-cat-cnn1', '#2ca02c'),\n", - " ('bert-large-cased-cat-cnn2', '#2ca02c'),\n", - " ('bert-large-cased-mix', '#f7b6d2'),\n", - " ('bert-large-cased-mix-cnn1', '#e377c2'),\n", - " ('bert-large-cased-mix-cnn2', '#e377c2')])" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "tasks = [\n", - " \"pos-ontonotes\",\n", - " \"nonterminal-ontonotes\",\n", - " \"constituent-ontonotes\",\n", - " \"dep-labeling-ewt\",\n", - " \"ner-ontonotes\",\n", - " \"srl-conll2012\",\n", - " \"coref-ontonotes-conll\",\n", - " \"spr1\",\n", - " \"spr2\",\n", - " \"dpr\",\n", - " \"ner-tacred\",\n", - " \"rel-tacred\",\n", - " \"rel-semeval\",\n", - " \"coref-gap\",\n", - " \"coref-gap-ontonotes\",\n", - " \"noun-verb\",\n", - "]\n", - "\n", - "# See https://bokeh.pydata.org/en/latest/docs/reference/palettes.html\n", - "_clist = bokeh.palettes.Category20[20]\n", - "exp_types_clist_idx = [\n", - " (\"glove\", 2), # orange\n", - " (\"cove\", 6), # deep red\n", - " (\"elmo-chars\", 18), # aqua\n", - " (\"elmo-ortho\", 8), # purple\n", - " (\"elmo-full\", 0), # blue\n", - " (\"openai-lex\", 16), # olive\n", - " (\"openai-cat\", 4), # green\n", - " (\"openai-mix\", 12), # pink\n", - " (\"openai\", 4), # green\n", - " (\"openai-bwb\", 12), # pink\n", - " (\"train-chars\", 10), # brown\n", - "]\n", - "# Make all BERT expts the same color\n", - "for bert_name in ['base-uncased', 'base-cased', 'large-uncased', 'large-cased']:\n", - " exp_types_clist_idx.append((f\"bert-{bert_name}-lex\", 16)) # olive\n", - " exp_types_clist_idx.append((f\"bert-{bert_name}-cat\", 4)) # green\n", - " exp_types_clist_idx.append((f\"bert-{bert_name}-mix\", 12)) # pink\n", - " \n", - "exp_types_colored = collections.OrderedDict()\n", - "# Use lighter versions for base model, darker for CNN\n", - "for k, v in exp_types_clist_idx:\n", - " exp_types_colored[k] = _clist[v + 1]\n", - " exp_types_colored[k+\"-cnn1\"] = _clist[v]\n", - " exp_types_colored[k+\"-cnn2\"] = _clist[v]\n", - "\n", - "def exp_type_sort_key(candidate):\n", - " exp_type = candidate.split(\" \", 1)[0]\n", - " return (exp_types.index(exp_type), candidate)\n", - "\n", - "def task_sort_key(candidate):\n", - " for i, name in enumerate(tasks):\n", - " if candidate.startswith(name):\n", - " return (i, candidate)\n", - " return (len(tasks), candidate)\n", - "\n", - "exp_types, palette = zip(*exp_types_colored.items())\n", - "fill_cmap = bokeh.transform.factor_cmap('exp_type', palette, exp_types)\n", - "\n", - "exp_types_colored" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [], - "source": [ - "def get_exp_type(exp_name):\n", - " m = re.match(r\"([a-z-]+)-edges-([a-z-]+)\", exp_name)\n", - " assert m is not None, f\"Unable to parse run name: {run_path}\"\n", - " prefix, task = m.groups()\n", - " return prefix\n", - "\n", - "def clean_task_name(task_name):\n", - " c1 = re.sub(r\"^edges-\", \"\", task_name)\n", - " c2 = re.sub(r\"-openai$\", \"\", c1)\n", - " return c2\n", - "\n", - "ID_COLS = ['run', 'task', 'split']\n", - "\n", - "def is_core_role(label):\n", - " return re.match(r\"^ARG[0-5A]$\", label) is not None\n", - "\n", - "def is_non_core_role(label):\n", - " return re.match(r\"^ARGM(-.+)?$\", label) is not None\n", - "\n", - "def is_core_or_noncore(label):\n", - " return is_core_role(label) or is_non_core_role(label)\n", - "\n", - "def is_srl_task(task):\n", - " return task.startswith(\"srl-\")\n", - "\n", - "def is_coref_task(task):\n", - " return task.startswith(\"coref-\")\n", - "\n", - "def is_constituent_task(task):\n", - " return task.startswith(\"constituent-\")\n", - "\n", - "def is_relation_task(task):\n", - " return task.startswith(\"rel-\")\n", - "\n", - "def is_positive_relation(label):\n", - " return (not label.startswith(\"_\")) and (label != \"no_relation\") and (label != \"Other\")\n", - "\n", - "def agg_label_group(df, task_predicate, label_predicate, group_name):\n", - " agg_map = {k:\"sum\" for k in df.columns if k.endswith(\"_count\")}\n", - " mask = df['task'].map(task_predicate) & df['label'].map(label_predicate)\n", - " sdf = df[mask].groupby(by=ID_COLS).agg(agg_map).reset_index()\n", - " sdf['label'] = group_name\n", - " return sdf\n", - "\n", - "def agg_stratifier_group(df, stratifier, key_predicate, group_name):\n", - " agg_map = {k:\"sum\" for k in df.columns if k.endswith(\"_count\")}\n", - "# mask = (df['stratifier'] == stratifier) & df['stratum_key'].map(key_predicate)\n", - " # Use this for short-circuit evaluation, so we don't call key_predicate on invalid keys\n", - " mask = [(s == stratifier and key_predicate(key)) \n", - " for s, key in zip(df['stratifier'], df['stratum_key'])]\n", - " sdf = df[mask].groupby(by=ID_COLS).agg(agg_map).reset_index()\n", - " sdf['label'] = group_name\n", - " return sdf \n", - "\n", - "def load_scores_file(filename, tag=None, seed=None):\n", - " df = pd.read_csv(filename, sep=\"\\t\", header=0)\n", - " df.drop(['Unnamed: 0'], axis='columns', inplace=True)\n", - " # df['task_raw'] = df['task'].copy()\n", - " df['task'] = df['task'].map(clean_task_name)\n", - " if not \"stratifier\" in df.columns:\n", - " df[\"stratifier\"] = None\n", - " if not \"stratum_key\" in df.columns:\n", - " df[\"stratum_key\"] = 0\n", - " \n", - " ###\n", - " # Add additional custom aggregations\n", - " _eg = []\n", - " # SRL core, non-core, and cleaned micro F1\n", - " _eg.append(agg_label_group(df, is_srl_task, is_core_role, \"_core_\"))\n", - " _eg.append(agg_label_group(df, is_srl_task, is_non_core_role, \"_non_core_\"))\n", - " _eg.append(agg_label_group(df, is_srl_task, is_core_or_noncore, \"_clean_micro_\"))\n", - " # Constituents: split into POS, nonterminals\n", - " _eg.append(agg_stratifier_group(df, 'info.height', lambda x: int(x) == 1, \"_pos_\"))\n", - " _eg.append(agg_stratifier_group(df, 'info.height', lambda x: int(x) > 1, \"_nonterminal_\"))\n", - " # Relations: ignore negative class (no_relation)\n", - " _eg.append(agg_label_group(df, is_relation_task, is_positive_relation, \"_clean_micro_\"))\n", - " df = pd.concat([df] + _eg, ignore_index=True, sort=False)\n", - " \n", - " df.insert(0, \"exp_name\", df['run'].map(lambda p: os.path.basename(os.path.dirname(p.strip(\"/\")))))\n", - " df.insert(1, \"exp_type\", df['exp_name'].map(get_exp_type))\n", - " if tag is not None:\n", - " df.insert(0, \"tag\", tag)\n", - " df.insert(1, \"seed\", seed)\n", - " return df" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [], - "source": [ - "def _make_display_name(task, label):\n", - " task_to_display_name = {\n", - " \"pos-ontonotes\": \"Part-of-Speech\",\n", - " \"nonterminal-ontonotes\": \"Constituents\",\n", - " \"dep-labeling-ewt\": \"Dependencies\",\n", - " \"ner-ontonotes\": \"Entities\",\n", - " \"srl-conll2012\": \"SRL\",\n", - " \"coref-ontonotes-conll\": \"OntoNotes coref.\",\n", - " \"spr1\": \"SPR1\",\n", - " \"spr2\": \"SPR2\",\n", - " \"dpr\": \"Winograd coref.\",\n", - " \"ner-tacred\": \"Entities (TACRED)\",\n", - " \"rel-tacred\": \"Relations (TACRED)\",\n", - " \"rel-semeval\": \"Relations (SemEval)\",\n", - " \"coref-gap\": \"GAP coref.\",\n", - " \"coref-gap-ontonotes\": \"GAP coref (train OOD)\",\n", - " \"noun-verb\": \"Noun-Verb\",\n", - " }\n", - " display_task = task_to_display_name[task]\n", - " if label in {\"_micro_avg_\", \"1\", None}:\n", - " return display_task\n", - " elif label == \"_clean_micro_\":\n", - " if task.startswith(\"srl-\"):\n", - " return f\"{display_task} (all)\"\n", - " else:\n", - " return display_task\n", - " elif label == \"_core_\":\n", - " return f\"{display_task} (core)\"\n", - " elif label == \"_non_core_\":\n", - " return f\"{display_task} (non-core)\"\n", - " elif label.endswith(\":_mean_\"):\n", - " return f\"{display_task} (mean)\"\n", - " else:\n", - " clean_label = label.strip(\"_\")\n", - " return f\"{display_task} ({clean_label})\"" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": { - "scrolled": false - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "['constituent-ontonotes' 'coref-ontonotes-conll' 'dep-labeling-ewt' 'dpr'\n", - " 'ner-ontonotes' 'spr1' 'spr2' 'srl-conll2012' 'nonterminal-ontonotes'\n", - " 'pos-ontonotes' 'rel-tacred' 'rel-semeval' 'noun-verb'\n", - " 'coref-gap-ontonotes' 'coref-gap' 'ner-tacred']\n", - "['openai-cat' 'openai-lex' 'openai-bwb' 'cove' 'elmo-chars' 'elmo-full'\n", - " 'elmo-ortho' 'glove' 'openai' 'bert-base-cased-cat' 'bert-base-cased-lex'\n", - " 'bert-base-uncased-cat' 'bert-base-uncased-lex' 'bert-large-cased-cat'\n", - " 'bert-large-cased-lex' 'bert-large-uncased-cat' 'bert-large-uncased-lex'\n", - " 'bert-base-cased-mix' 'bert-base-uncased-mix' 'bert-large-cased-mix'\n", - " 'bert-large-uncased-mix' 'openai-mix']\n" - ] - } - ], - "source": [ - "score_files = []\n", - "score_files = [\n", - " (\"base\", \"/nfs/jsalt/home/iftenney/exp/edges-20180921-openai/scores_cm.tsv\"),\n", - " (\"base\", \"/nfs/jsalt/home/iftenney/exp/edges-20180922-openai/scores_cm.tsv\"),\n", - " (\"base\", \"/nfs/jsalt/home/iftenney/exp/final_20180927/base/scores_cm.tsv\"),\n", - " (\"base\", \"/nfs/jsalt/exp/edges-20190124-bert/scores.tsv\"),\n", - " (\"base\", \"/nfs/jsalt/exp/edges-20190125-bert-splitconst/scores.tsv\"),\n", - " (\"base\", \"/nfs/jsalt/exp/edges-20190125-bert-large/scores.tsv\"),\n", - " (\"base\", \"/nfs/jsalt/exp/edges-20190129-bert-mix/scores.tsv\"),\n", - " (\"base\", \"/nfs/jsalt/exp/edges-20190205-tacred/scores.tsv\"),\n", - " (\"base\", \"/nfs/jsalt/exp/edges-20190205-semeval/scores.tsv\"),\n", - " (\"base\", \"/nfs/jsalt/exp/edges-20190205-noun-verb/scores.tsv\"),\n", - " (\"base\", \"/nfs/jsalt/exp/edges-20190207-gap/scores.tsv\"),\n", - " (\"base\", \"/nfs/jsalt/exp/edges-20190209-openai-mix/scores.tsv\"),\n", - " (\"bow\", \"/nfs/jsalt/exp/edges-20190220-rel-bow/scores.tsv\"),\n", - " (\"bow\", \"/nfs/jsalt/exp/edges-20190220-core-bow/scores.tsv\"),\n", - " (\"cnn1\", \"/nfs/jsalt/home/iftenney/exp/final_20180927/cnn1/scores_cm.tsv\"),\n", - " (\"cnn2\", \"/nfs/jsalt/home/iftenney/exp/final_20180927/cnn2/scores_cm.tsv\"),\n", - "]\n", - "\n", - "dfs = []\n", - "for tag, score_file in score_files:\n", - " df = load_scores_file(score_file, tag=tag)\n", - " dfs.append(df)\n", - "\n", - "# Load cross-val score files\n", - "for seed in [100,101,102,103,104]:\n", - " df = load_scores_file(f\"/nfs/jsalt/exp/edges-20190204-dpr-{seed:d}/scores.tsv\", \n", - " tag=\"base\", seed=seed)\n", - " dfs.append(df)\n", - " df = load_scores_file(f\"/nfs/jsalt/exp/edges-20190213-dpr-openai-mix-{seed:d}/scores.tsv\", \n", - " tag=\"base\", seed=seed)\n", - " dfs.append(df)\n", - " df = load_scores_file(f\"/nfs/jsalt/exp/edges-20190220-dpr-bert-cat-{seed:d}/scores.tsv\", \n", - " tag=\"base\", seed=seed)\n", - " dfs.append(df)\n", - "\n", - "df = pd.concat(dfs, ignore_index=True, sort=False)\n", - "df['display_col'] = [\"%s (%s)\" % et for et in zip(df.exp_type, df.tag)]\n", - "print(df['task'].unique())\n", - "print(df['exp_type'].unique())" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [], - "source": [ - "def harmonic_mean(a, b):\n", - " return 2 * a * b / (a + b)\n", - "\n", - "df['pred_pos_count'] = df.tp_count + df.fp_count\n", - "df['true_pos_count'] = df.tp_count + df.fn_count\n", - "df['total_count'] = df.tp_count + df.tn_count + df.fp_count + df.fn_count\n", - "\n", - "# NOTE: this overwrites any _macro_avg_ rows by recomputing the micro-average!\n", - "df['accuracy'] = (df.tp_count + df.tn_count) / df.total_count\n", - "df['precision'] = df.tp_count / df.pred_pos_count\n", - "df['recall'] = df.tp_count / df.true_pos_count\n", - "df['f1_score'] = harmonic_mean(df.precision, df.recall).fillna(0)\n", - "\n", - "# Approximate error intervals using normal approximation\n", - "# https://en.wikipedia.org/wiki/Binomial_proportion_confidence_interval#Wilson_score_interval\n", - "z = 1.96 # 95% confidence\n", - "df['accuracy_errn95'] = z * (df.accuracy * (1 - df.accuracy) / df.total_count).map(np.sqrt)\n", - "df['precision_errn95'] = z * (df.precision * (1 - df.precision) / df.pred_pos_count).map(np.sqrt)\n", - "df['recall_errn95'] = z * (df.recall * (1 - df.recall) / df.true_pos_count).map(np.sqrt)\n", - "# This is probably not the right way to combine for F1 score - TODO to figure this out?\n", - "df['f1_errn95'] = harmonic_mean(df.precision_errn95, df.recall_errn95)\n", - "\n", - "def _get_final_score(row):\n", - " return row['f1_score'], row['f1_errn95']\n", - "\n", - "df['score'], df['score_errn95'] = zip(*(_get_final_score(row) for i, row in df.iterrows()))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "For DPR, we need to average across multiple runs to get a good estimate of performance." - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [], - "source": [ - "mask = df['task'] == 'dpr'\n", - "mask &= df['label'] != \"__run_info__\"\n", - "mask &= df['seed'].notnull()\n", - "gb_cols = [\"tag\", \"exp_name\", \"exp_type\", \"task\", \"label\", \"split\", \"display_col\"]\n", - "gb = df[mask].groupby(by=gb_cols)\n", - "new_rows = []\n", - "for key, idxs in gb.groups.items():\n", - " new_row = dict(zip(gb_cols, key))\n", - " new_row[\"seed\"] = \"_mean_\"\n", - " new_row[\"score\"] = df.loc[idxs, \"score\"].mean()\n", - " new_row[\"score_errn95\"] = 1.96 * np.sqrt(df.loc[idxs, \"score\"].var()/len(idxs))\n", - " new_rows.append(new_row)\n", - " \n", - "agg_df = pd.DataFrame.from_records(new_rows)\n", - "df = pd.concat([df, agg_df], ignore_index=True, sort=False)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "For SemEval 2010 Task 8, the official metric is macro-averaged F1 over non-Other labels. Compute this so we can compare to SOTA." - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": { - "scrolled": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "run,split,score\n", - "/nfs/jsalt/exp/edges-20190205-semeval/bert-base-uncased-cat-edges-rel-semeval/run,test,0.7033\n", - "/nfs/jsalt/exp/edges-20190205-semeval/bert-base-uncased-cat-edges-rel-semeval/run,val,0.7056\n", - "/nfs/jsalt/exp/edges-20190205-semeval/bert-base-uncased-lex-edges-rel-semeval/run,test,0.5326\n", - "/nfs/jsalt/exp/edges-20190205-semeval/bert-base-uncased-lex-edges-rel-semeval/run,val,0.5021\n", - "/nfs/jsalt/exp/edges-20190205-semeval/bert-base-uncased-mix-edges-rel-semeval/run,test,0.7441\n", - "/nfs/jsalt/exp/edges-20190205-semeval/bert-base-uncased-mix-edges-rel-semeval/run,val,0.7556\n", - "/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-cat-edges-rel-semeval/run,test,0.7041\n", - "/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-cat-edges-rel-semeval/run,val,0.6980\n", - "/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-lex-edges-rel-semeval/run,test,0.5254\n", - "/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-lex-edges-rel-semeval/run,val,0.5309\n", - "/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run,test,0.7558\n", - "/nfs/jsalt/exp/edges-20190205-semeval/bert-large-uncased-mix-edges-rel-semeval/run,val,0.7583\n", - "/nfs/jsalt/exp/edges-20190205-semeval/cove-edges-rel-semeval/run,test,0.5385\n", - "/nfs/jsalt/exp/edges-20190205-semeval/cove-edges-rel-semeval/run,val,0.6719\n", - "/nfs/jsalt/exp/edges-20190205-semeval/elmo-chars-edges-rel-semeval/run,test,0.5096\n", - "/nfs/jsalt/exp/edges-20190205-semeval/elmo-chars-edges-rel-semeval/run,val,0.4717\n", - "/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run,test,0.7006\n", - "/nfs/jsalt/exp/edges-20190205-semeval/elmo-full-edges-rel-semeval/run,val,0.6831\n", - "/nfs/jsalt/exp/edges-20190205-semeval/elmo-ortho-edges-rel-semeval/run_seed_0,test,0.5143\n", - "/nfs/jsalt/exp/edges-20190205-semeval/elmo-ortho-edges-rel-semeval/run_seed_0,val,0.4902\n", - "/nfs/jsalt/exp/edges-20190205-semeval/glove-edges-rel-semeval/run,test,0.4474\n", - "/nfs/jsalt/exp/edges-20190205-semeval/glove-edges-rel-semeval/run,val,0.4846\n", - "/nfs/jsalt/exp/edges-20190205-semeval/openai-cat-edges-rel-semeval/run,test,0.7330\n", - "/nfs/jsalt/exp/edges-20190205-semeval/openai-cat-edges-rel-semeval/run,val,0.7471\n", - "/nfs/jsalt/exp/edges-20190205-semeval/openai-lex-edges-rel-semeval/run,test,0.5348\n", - "/nfs/jsalt/exp/edges-20190205-semeval/openai-lex-edges-rel-semeval/run,val,0.5258\n", - "/nfs/jsalt/exp/edges-20190209-openai-mix/openai-mix-edges-rel-semeval/run,test,0.7214\n", - "/nfs/jsalt/exp/edges-20190209-openai-mix/openai-mix-edges-rel-semeval/run,val,0.7444\n", - "/nfs/jsalt/exp/edges-20190220-rel-bow//bert-base-uncased-lex-edges-rel-semeval/run,test,0.6458\n", - "/nfs/jsalt/exp/edges-20190220-rel-bow//bert-base-uncased-lex-edges-rel-semeval/run,val,0.6378\n", - "/nfs/jsalt/exp/edges-20190220-rel-bow//bert-large-uncased-lex-edges-rel-semeval/run,test,0.6323\n", - "/nfs/jsalt/exp/edges-20190220-rel-bow//bert-large-uncased-lex-edges-rel-semeval/run,val,0.6236\n", - "/nfs/jsalt/exp/edges-20190220-rel-bow//elmo-chars-edges-rel-semeval/run,test,0.6478\n", - "/nfs/jsalt/exp/edges-20190220-rel-bow//elmo-chars-edges-rel-semeval/run,val,0.6178\n", - "/nfs/jsalt/exp/edges-20190220-rel-bow//glove-edges-rel-semeval/run,test,0.5604\n", - "/nfs/jsalt/exp/edges-20190220-rel-bow//glove-edges-rel-semeval/run,val,0.6325\n", - "/nfs/jsalt/exp/edges-20190220-rel-bow//openai-lex-edges-rel-semeval/run,test,0.6279\n", - "/nfs/jsalt/exp/edges-20190220-rel-bow//openai-lex-edges-rel-semeval/run,val,0.6414\n", - "\n" - ] - } - ], - "source": [ - "mask = df['task'] == 'rel-semeval'\n", - "mask &= df['split'].notnull()\n", - "mask &= df['label'].map(is_positive_relation)\n", - "_id_cols = ['run', 'split']\n", - "_agg_cols = ['score']\n", - "gb = df[mask][_id_cols + _agg_cols].groupby(_id_cols)\n", - "afd = gb.agg('mean')\n", - "afd = afd.reset_index()\n", - "\n", - "csv_args = dict(float_format=\"%.4f\")\n", - "print(afd.to_csv(index=False, **csv_args))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Compute clean metrics for each task\n", - "\n", - "For most tasks this is just the micro or macro average F1, but we need to ignore the 0 label for coref, and drop references and continuations for SRL." - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": { - "scrolled": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "269\n" - ] - }, - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
tagseedexp_nameexp_typelabelnum_epochsnum_stepsruntasksplit...precisionrecallf1_scoreaccuracy_errn95precision_errn95recall_errn95f1_errn95scorescore_errn95display_row
0baseNoneopenai-cat-edges-coref-ontonotes-conllopenai-cat1NaNNaN/nfs/jsalt/home/iftenney/exp/edges-20180921-op...coref-ontonotes-conllval...0.8552630.8172580.8358290.0030980.0092580.0099410.0095870.8358290.009587coref-ontonotes-conll-1
1baseNoneopenai-lex-edges-coref-ontonotes-conllopenai-lex1NaNNaN/nfs/jsalt/home/iftenney/exp/edges-20180921-op...coref-ontonotes-conllval...0.8087710.6606960.7272730.0037680.0111920.0121790.0116650.7272730.011665coref-ontonotes-conll-1
2baseNoneopenai-bwb-edges-coref-ontonotes-conllopenai-bwb1NaNNaN/nfs/jsalt/home/iftenney/exp/edges-20180922-op...coref-ontonotes-conllval...0.8558440.8108850.8327580.0031180.0092820.0100730.0096610.8327580.009661coref-ontonotes-conll-1
3baseNonecove-edges-coref-ontonotes-conllcove1NaNNaN/nfs/jsalt/home/iftenney/exp/final_20180927/ba...coref-ontonotes-conllval...0.8350320.7619700.7968300.0033800.0099940.0109550.0104520.7968300.010452coref-ontonotes-conll-1
4baseNoneelmo-chars-edges-coref-ontonotes-conllelmo-chars1NaNNaN/nfs/jsalt/home/iftenney/exp/final_20180927/ba...coref-ontonotes-conllval...0.8025930.7142610.7558550.0036510.0108530.0116210.0112240.7558550.011224coref-ontonotes-conll-1
5baseNoneelmo-full-edges-coref-ontonotes-conllelmo-full1NaNNaN/nfs/jsalt/home/iftenney/exp/final_20180927/ba...coref-ontonotes-conllval...0.8611560.8343090.8475200.0030030.0090360.0095640.0092930.8475200.009293coref-ontonotes-conll-1
6baseNoneelmo-ortho-edges-coref-ontonotes-conllelmo-ortho1NaNNaN/nfs/jsalt/home/iftenney/exp/final_20180927/ba...coref-ontonotes-conllval...0.8121750.7812610.7964180.0034230.0102430.0106340.0104350.7964180.010435coref-ontonotes-conll-1
7baseNoneglove-edges-coref-ontonotes-conllglove1NaNNaN/nfs/jsalt/home/iftenney/exp/final_20180927/ba...coref-ontonotes-conllval...0.7931720.6842920.7347200.0037630.0112170.0119560.0115750.7347200.011575coref-ontonotes-conll-1
8baseNonebert-base-uncased-cat-edges-coref-ontonotes-conllbert-base-uncased-cat1NaNNaN/nfs/jsalt/exp/edges-20190124-bert/bert-base-u...coref-ontonotes-conllval...0.8922360.8926970.8924670.0025670.0079740.0079610.0079680.8924670.007968coref-ontonotes-conll-1
9baseNonebert-base-uncased-lex-edges-coref-ontonotes-conllbert-base-uncased-lex1NaNNaN/nfs/jsalt/exp/edges-20190124-bert/bert-base-u...coref-ontonotes-conllval...0.7979800.7211510.7576220.0036510.0108640.0115350.0111890.7576220.011189coref-ontonotes-conll-1
10baseNonebert-large-uncased-cat-edges-coref-ontonotes-c...bert-large-uncased-cat1NaNNaN/nfs/jsalt/exp/edges-20190125-bert-large/bert-...coref-ontonotes-conllval...0.8945750.9032040.8988690.0024990.0078620.0076060.0077320.8988690.007732coref-ontonotes-conll-1
11baseNonebert-large-uncased-lex-edges-coref-ontonotes-c...bert-large-uncased-lex1NaNNaN/nfs/jsalt/exp/edges-20190125-bert-large/bert-...coref-ontonotes-conllval...0.8036090.7209780.7600540.0036290.0107890.0115370.0111500.7600540.011150coref-ontonotes-conll-1
12baseNonebert-base-uncased-mix-edges-coref-ontonotes-conllbert-base-uncased-mix1NaNNaN/nfs/jsalt/exp/edges-20190129-bert-mix/bert-ba...coref-ontonotes-conllval...0.9059960.9030310.9045110.0024240.0075190.0076120.0075650.9045110.007565coref-ontonotes-conll-1
13baseNonebert-large-uncased-mix-edges-coref-ontonotes-c...bert-large-uncased-mix1NaNNaN/nfs/jsalt/exp/edges-20190129-bert-mix/bert-la...coref-ontonotes-conllval...0.9200960.9242160.9221520.0022010.0069590.0068080.0068820.9221520.006882coref-ontonotes-conll-1
14baseNoneopenai-mix-edges-coref-ontonotes-conllopenai-mix1NaNNaN/nfs/jsalt/exp/edges-20190209-openai-mix/opena...coref-ontonotes-conllval...0.8611450.8630730.8621080.0028880.0088850.0088430.0088640.8621080.008864coref-ontonotes-conll-1
15bowNonebert-base-uncased-lex-edges-coref-ontonotes-conllbert-base-uncased-lex1NaNNaN/nfs/jsalt/exp/edges-20190220-core-bow/bert-ba...coref-ontonotes-conllval...0.8020810.7566310.7786940.0035390.0105520.0110380.0107900.7786940.010790coref-ontonotes-conll-1
16bowNonebert-large-uncased-lex-edges-coref-ontonotes-c...bert-large-uncased-lex1NaNNaN/nfs/jsalt/exp/edges-20190220-core-bow/bert-la...coref-ontonotes-conllval...0.8040840.7528420.7776200.0035410.0105510.0110960.0108170.7776200.010817coref-ontonotes-conll-1
17bowNoneelmo-chars-edges-coref-ontonotes-conllelmo-chars1NaNNaN/nfs/jsalt/exp/edges-20190220-core-bow/elmo-ch...coref-ontonotes-conllval...0.8084310.7464690.7762160.0035400.0105350.0111900.0108530.7762160.010853coref-ontonotes-conll-1
18bowNoneglove-edges-coref-ontonotes-conllglove1NaNNaN/nfs/jsalt/exp/edges-20190220-core-bow/glove-e...coref-ontonotes-conllval...0.8081520.7342400.7694250.0035750.0106260.0113630.0109820.7694250.010982coref-ontonotes-conll-1
19bowNoneopenai-lex-edges-coref-ontonotes-conllopenai-lex1NaNNaN/nfs/jsalt/exp/edges-20190220-core-bow/openai-...coref-ontonotes-conllval...0.8200210.6701690.7375600.0037050.0109310.0120940.0114830.7375600.011483coref-ontonotes-conll-1
20cnn1Noneelmo-chars-edges-coref-ontonotes-conllelmo-chars1NaNNaN/nfs/jsalt/home/iftenney/exp/final_20180927/cn...coref-ontonotes-conllval...0.8241320.7764380.7995740.0033830.0100890.0107170.0103940.7995740.010394coref-ontonotes-conll-1
21cnn2Noneelmo-chars-edges-coref-ontonotes-conllelmo-chars1NaNNaN/nfs/jsalt/home/iftenney/exp/final_20180927/cn...coref-ontonotes-conllval...0.8261670.7743710.7994310.0033800.0100690.0107520.0103990.7994310.010399coref-ontonotes-conll-1
22baseNoneopenai-cat-edges-dep-labeling-ewtopenai-cat_micro_avg_NaNNaN/nfs/jsalt/home/iftenney/exp/edges-20180921-op...dep-labeling-ewtval...0.9376470.9043010.9206720.0000980.0030450.0036390.0033160.9206720.003316dep-labeling-ewt-_micro_avg_
23baseNoneopenai-lex-edges-dep-labeling-ewtopenai-lex_micro_avg_NaNNaN/nfs/jsalt/home/iftenney/exp/edges-20180921-op...dep-labeling-ewtval...0.8879630.6915570.7775490.0001550.0044210.0057130.0049840.7775490.004984dep-labeling-ewt-_micro_avg_
24baseNoneopenai-bwb-edges-dep-labeling-ewtopenai-bwb_micro_avg_NaNNaN/nfs/jsalt/home/iftenney/exp/edges-20180922-op...dep-labeling-ewtval...0.9388560.9050180.9216260.0000970.0030180.0036260.0032950.9216260.003295dep-labeling-ewt-_micro_avg_
25baseNonecove-edges-dep-labeling-ewtcove_micro_avg_NaNNaN/nfs/jsalt/home/iftenney/exp/final_20180927/ba...dep-labeling-ewtval...0.9248710.8780570.9008560.0001090.0033460.0040470.0036640.9008560.003664dep-labeling-ewt-_micro_avg_
26baseNoneelmo-chars-edges-dep-labeling-ewtelmo-chars_micro_avg_NaNNaN/nfs/jsalt/home/iftenney/exp/final_20180927/ba...dep-labeling-ewtval...0.8989030.7308640.8062210.0001460.0041350.0054860.0047160.8062210.004716dep-labeling-ewt-_micro_avg_
27baseNoneelmo-full-edges-dep-labeling-ewtelmo-full_micro_avg_NaNNaN/nfs/jsalt/home/iftenney/exp/final_20180927/ba...dep-labeling-ewtval...0.9571740.9274790.9420930.0000830.0025440.0032080.0028380.9420930.002838dep-labeling-ewt-_micro_avg_
28baseNoneelmo-ortho-edges-dep-labeling-ewtelmo-ortho_micro_avg_NaNNaN/nfs/jsalt/home/iftenney/exp/final_20180927/ba...dep-labeling-ewtval...0.9125830.8003190.8527720.0001300.0037310.0049450.0042530.8527720.004253dep-labeling-ewt-_micro_avg_
29baseNoneglove-edges-dep-labeling-ewtglove_micro_avg_NaNNaN/nfs/jsalt/home/iftenney/exp/final_20180927/ba...dep-labeling-ewtval...0.8997810.6714850.7690480.0001560.0043000.0058090.0049420.7690480.004942dep-labeling-ewt-_micro_avg_
..................................................................
239baseNoneelmo-full-edges-rel-tacredelmo-full_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190205-tacred/elmo-full...rel-tacredval...0.7054020.4131710.5211140.0001350.0158340.0130900.0143320.5211140.014332rel-tacred-_clean_micro_
240baseNoneelmo-ortho-edges-rel-tacredelmo-ortho_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190205-tacred/elmo-orth...rel-tacredval...0.6144170.2336280.3385310.0001480.0209830.0112490.0146460.3385310.014646rel-tacred-_clean_micro_
241baseNoneglove-edges-rel-tacredglove_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190205-tacred/glove-edg...rel-tacredval...0.6125490.1742090.2712690.0001500.0242850.0100830.0142490.2712690.014249rel-tacred-_clean_micro_
242baseNoneopenai-cat-edges-rel-tacredopenai-cat_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190205-tacred/openai-ca...rel-tacredval...0.7076660.3090510.4302180.0001410.0182970.0122840.0146990.4302180.014699rel-tacred-_clean_micro_
243baseNoneopenai-lex-edges-rel-tacredopenai-lex_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190205-tacred/openai-le...rel-tacredval...0.5794540.1328180.2161030.0001520.0274100.0090220.0135760.2161030.013576rel-tacred-_clean_micro_
244baseNoneopenai-mix-edges-rel-tacredopenai-mix_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190209-openai-mix/opena...rel-tacredval...0.6822540.3274470.4425110.0001410.0178660.0124750.0146920.4425110.014692rel-tacred-_clean_micro_
245bowNonebert-base-uncased-lex-edges-rel-tacredbert-base-uncased-lex_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190220-rel-bow//bert-ba...rel-tacredval...0.6460130.2474250.3578080.0001460.0205410.0114710.0147210.3578080.014721rel-tacred-_clean_micro_
246bowNonebert-large-uncased-lex-edges-rel-tacredbert-large-uncased-lex_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190220-rel-bow//bert-la...rel-tacredval...0.6504980.1800960.2820920.0001490.0240900.0102150.0143470.2820920.014347rel-tacred-_clean_micro_
247bowNoneelmo-chars-edges-rel-tacredelmo-chars_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190220-rel-bow//elmo-ch...rel-tacredval...0.6391630.2864240.3955790.0001450.0190710.0120180.0147450.3955790.014745rel-tacred-_clean_micro_
248bowNoneglove-edges-rel-tacredglove_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190220-rel-bow//glove-e...rel-tacredval...0.6357890.2588300.3678910.0001460.0200490.0116430.0147320.3678910.014732rel-tacred-_clean_micro_
249bowNoneopenai-lex-edges-rel-tacredopenai-lex_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190220-rel-bow//openai-...rel-tacredval...0.6179510.2419060.3477000.0001480.0206450.0113840.0146760.3477000.014676rel-tacred-_clean_micro_
250baseNonebert-base-uncased-cat-edges-rel-semevalbert-base-uncased-cat_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190205-semeval/bert-bas...rel-semevalval...0.8914730.7180020.7953890.0017700.0219130.0284500.0247570.7953890.024757rel-semeval-_clean_micro_
251baseNonebert-base-uncased-lex-edges-rel-semevalbert-base-uncased-lex_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190205-semeval/bert-bas...rel-semevalval...0.7546530.4641000.5747420.0023950.0346920.0315310.0330360.5747420.033036rel-semeval-_clean_micro_
252baseNonebert-base-uncased-mix-edges-rel-semevalbert-base-uncased-mix_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190205-semeval/bert-bas...rel-semevalval...0.8916670.7793960.8317600.0016370.0210180.0262170.0233320.8317600.023332rel-semeval-_clean_micro_
253baseNonebert-large-uncased-cat-edges-rel-semevalbert-large-uncased-cat_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190205-semeval/bert-lar...rel-semevalval...0.8764480.7086370.7836590.0018210.0231380.0287290.0256320.7836590.025632rel-semeval-_clean_micro_
254baseNonebert-large-uncased-lex-edges-rel-semevalbert-large-uncased-lex_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190205-semeval/bert-lar...rel-semevalval...0.7577740.4817900.5890590.0023710.0339720.0315920.0327390.5890590.032739rel-semeval-_clean_micro_
255baseNonebert-large-uncased-mix-edges-rel-semevalbert-large-uncased-mix_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190205-semeval/bert-lar...rel-semevalval...0.8943660.7929240.8405960.0016000.0206390.0256200.0228610.8405960.022861rel-semeval-_clean_micro_
256baseNonecove-edges-rel-semevalcove_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190205-semeval/cove-edg...rel-semevalval...0.8716930.6857440.7676180.0018750.0238400.0293510.0263100.7676180.026310rel-semeval-_clean_micro_
257baseNoneelmo-chars-edges-rel-semevalelmo-chars_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190205-semeval/elmo-cha...rel-semevalval...0.7042740.4287200.5329880.0025020.0369820.0312900.0338990.5329880.033899rel-semeval-_clean_micro_
258baseNoneelmo-full-edges-rel-semevalelmo-full_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190205-semeval/elmo-ful...rel-semevalval...0.8690010.6971900.7736720.0018580.0238160.0290510.0261740.7736720.026174rel-semeval-_clean_micro_
259baseNoneelmo-ortho-edges-rel-semevalelmo-ortho_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190205-semeval/elmo-ort...rel-semevalval...0.7448630.4526530.5631070.0024220.0353570.0314710.0333010.5631070.033301rel-semeval-_clean_micro_
260baseNoneglove-edges-rel-semevalglove_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190205-semeval/glove-ed...rel-semevalval...0.7808470.4412070.5638300.0023880.0347950.0313940.0330070.5638300.033007rel-semeval-_clean_micro_
261baseNoneopenai-cat-edges-rel-semevalopenai-cat_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190205-semeval/openai-c...rel-semevalval...0.8710430.7731530.8191840.0017030.0224920.0264790.0243230.8191840.024323rel-semeval-_clean_micro_
262baseNoneopenai-lex-edges-rel-semevalopenai-lex_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190205-semeval/openai-l...rel-semevalval...0.7650000.4776270.5880850.0023650.0339270.0315810.0327120.5880850.032712rel-semeval-_clean_micro_
263baseNoneopenai-mix-edges-rel-semevalopenai-mix_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190209-openai-mix/opena...rel-semevalval...0.8550560.7918830.8222580.0017050.0231290.0256670.0243320.8222580.024332rel-semeval-_clean_micro_
264bowNonebert-base-uncased-lex-edges-rel-semevalbert-base-uncased-lex_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190220-rel-bow//bert-ba...rel-semevalval...0.8137380.6409990.7171130.0020650.0277340.0303300.0289740.7171130.028974rel-semeval-_clean_micro_
265bowNonebert-large-uncased-lex-edges-rel-semevalbert-large-uncased-lex_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190220-rel-bow//bert-la...rel-semevalval...0.7862600.6430800.7074990.0021160.0286600.0302910.0294530.7074990.029453rel-semeval-_clean_micro_
266bowNoneelmo-chars-edges-rel-semevalelmo-chars_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190220-rel-bow//elmo-ch...rel-semevalval...0.8023720.6337150.7081400.0020970.0283300.0304610.0293570.7081400.029357rel-semeval-_clean_micro_
267bowNoneglove-edges-rel-semevalglove_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190220-rel-bow//glove-e...rel-semevalval...0.8062420.6451610.7167630.0020730.0279350.0302510.0290470.7167630.029047rel-semeval-_clean_micro_
268bowNoneopenai-lex-edges-rel-semevalopenai-lex_clean_micro_NaNNaN/nfs/jsalt/exp/edges-20190220-rel-bow//openai-...rel-semevalval...0.8251660.6482830.7261070.0020310.0270940.0301910.0285580.7261070.028558rel-semeval-_clean_micro_
\n", - "

269 rows × 31 columns

\n", - "
" - ], - "text/plain": [ - " tag seed exp_name \\\n", - "0 base None openai-cat-edges-coref-ontonotes-conll \n", - "1 base None openai-lex-edges-coref-ontonotes-conll \n", - "2 base None openai-bwb-edges-coref-ontonotes-conll \n", - "3 base None cove-edges-coref-ontonotes-conll \n", - "4 base None elmo-chars-edges-coref-ontonotes-conll \n", - "5 base None elmo-full-edges-coref-ontonotes-conll \n", - "6 base None elmo-ortho-edges-coref-ontonotes-conll \n", - "7 base None glove-edges-coref-ontonotes-conll \n", - "8 base None bert-base-uncased-cat-edges-coref-ontonotes-conll \n", - "9 base None bert-base-uncased-lex-edges-coref-ontonotes-conll \n", - "10 base None bert-large-uncased-cat-edges-coref-ontonotes-c... \n", - "11 base None bert-large-uncased-lex-edges-coref-ontonotes-c... \n", - "12 base None bert-base-uncased-mix-edges-coref-ontonotes-conll \n", - "13 base None bert-large-uncased-mix-edges-coref-ontonotes-c... \n", - "14 base None openai-mix-edges-coref-ontonotes-conll \n", - "15 bow None bert-base-uncased-lex-edges-coref-ontonotes-conll \n", - "16 bow None bert-large-uncased-lex-edges-coref-ontonotes-c... \n", - "17 bow None elmo-chars-edges-coref-ontonotes-conll \n", - "18 bow None glove-edges-coref-ontonotes-conll \n", - "19 bow None openai-lex-edges-coref-ontonotes-conll \n", - "20 cnn1 None elmo-chars-edges-coref-ontonotes-conll \n", - "21 cnn2 None elmo-chars-edges-coref-ontonotes-conll \n", - "22 base None openai-cat-edges-dep-labeling-ewt \n", - "23 base None openai-lex-edges-dep-labeling-ewt \n", - "24 base None openai-bwb-edges-dep-labeling-ewt \n", - "25 base None cove-edges-dep-labeling-ewt \n", - "26 base None elmo-chars-edges-dep-labeling-ewt \n", - "27 base None elmo-full-edges-dep-labeling-ewt \n", - "28 base None elmo-ortho-edges-dep-labeling-ewt \n", - "29 base None glove-edges-dep-labeling-ewt \n", - ".. ... ... ... \n", - "239 base None elmo-full-edges-rel-tacred \n", - "240 base None elmo-ortho-edges-rel-tacred \n", - "241 base None glove-edges-rel-tacred \n", - "242 base None openai-cat-edges-rel-tacred \n", - "243 base None openai-lex-edges-rel-tacred \n", - "244 base None openai-mix-edges-rel-tacred \n", - "245 bow None bert-base-uncased-lex-edges-rel-tacred \n", - "246 bow None bert-large-uncased-lex-edges-rel-tacred \n", - "247 bow None elmo-chars-edges-rel-tacred \n", - "248 bow None glove-edges-rel-tacred \n", - "249 bow None openai-lex-edges-rel-tacred \n", - "250 base None bert-base-uncased-cat-edges-rel-semeval \n", - "251 base None bert-base-uncased-lex-edges-rel-semeval \n", - "252 base None bert-base-uncased-mix-edges-rel-semeval \n", - "253 base None bert-large-uncased-cat-edges-rel-semeval \n", - "254 base None bert-large-uncased-lex-edges-rel-semeval \n", - "255 base None bert-large-uncased-mix-edges-rel-semeval \n", - "256 base None cove-edges-rel-semeval \n", - "257 base None elmo-chars-edges-rel-semeval \n", - "258 base None elmo-full-edges-rel-semeval \n", - "259 base None elmo-ortho-edges-rel-semeval \n", - "260 base None glove-edges-rel-semeval \n", - "261 base None openai-cat-edges-rel-semeval \n", - "262 base None openai-lex-edges-rel-semeval \n", - "263 base None openai-mix-edges-rel-semeval \n", - "264 bow None bert-base-uncased-lex-edges-rel-semeval \n", - "265 bow None bert-large-uncased-lex-edges-rel-semeval \n", - "266 bow None elmo-chars-edges-rel-semeval \n", - "267 bow None glove-edges-rel-semeval \n", - "268 bow None openai-lex-edges-rel-semeval \n", - "\n", - " exp_type label num_epochs num_steps \\\n", - "0 openai-cat 1 NaN NaN \n", - "1 openai-lex 1 NaN NaN \n", - "2 openai-bwb 1 NaN NaN \n", - "3 cove 1 NaN NaN \n", - "4 elmo-chars 1 NaN NaN \n", - "5 elmo-full 1 NaN NaN \n", - "6 elmo-ortho 1 NaN NaN \n", - "7 glove 1 NaN NaN \n", - "8 bert-base-uncased-cat 1 NaN NaN \n", - "9 bert-base-uncased-lex 1 NaN NaN \n", - "10 bert-large-uncased-cat 1 NaN NaN \n", - "11 bert-large-uncased-lex 1 NaN NaN \n", - "12 bert-base-uncased-mix 1 NaN NaN \n", - "13 bert-large-uncased-mix 1 NaN NaN \n", - "14 openai-mix 1 NaN NaN \n", - "15 bert-base-uncased-lex 1 NaN NaN \n", - "16 bert-large-uncased-lex 1 NaN NaN \n", - "17 elmo-chars 1 NaN NaN \n", - "18 glove 1 NaN NaN \n", - "19 openai-lex 1 NaN NaN \n", - "20 elmo-chars 1 NaN NaN \n", - "21 elmo-chars 1 NaN NaN \n", - "22 openai-cat _micro_avg_ NaN NaN \n", - "23 openai-lex _micro_avg_ NaN NaN \n", - "24 openai-bwb _micro_avg_ NaN NaN \n", - "25 cove _micro_avg_ NaN NaN \n", - "26 elmo-chars _micro_avg_ NaN NaN \n", - "27 elmo-full _micro_avg_ NaN NaN \n", - "28 elmo-ortho _micro_avg_ NaN NaN \n", - "29 glove _micro_avg_ NaN NaN \n", - ".. ... ... ... ... \n", - "239 elmo-full _clean_micro_ NaN NaN \n", - "240 elmo-ortho _clean_micro_ NaN NaN \n", - "241 glove _clean_micro_ NaN NaN \n", - "242 openai-cat _clean_micro_ NaN NaN \n", - "243 openai-lex _clean_micro_ NaN NaN \n", - "244 openai-mix _clean_micro_ NaN NaN \n", - "245 bert-base-uncased-lex _clean_micro_ NaN NaN \n", - "246 bert-large-uncased-lex _clean_micro_ NaN NaN \n", - "247 elmo-chars _clean_micro_ NaN NaN \n", - "248 glove _clean_micro_ NaN NaN \n", - "249 openai-lex _clean_micro_ NaN NaN \n", - "250 bert-base-uncased-cat _clean_micro_ NaN NaN \n", - "251 bert-base-uncased-lex _clean_micro_ NaN NaN \n", - "252 bert-base-uncased-mix _clean_micro_ NaN NaN \n", - "253 bert-large-uncased-cat _clean_micro_ NaN NaN \n", - "254 bert-large-uncased-lex _clean_micro_ NaN NaN \n", - "255 bert-large-uncased-mix _clean_micro_ NaN NaN \n", - "256 cove _clean_micro_ NaN NaN \n", - "257 elmo-chars _clean_micro_ NaN NaN \n", - "258 elmo-full _clean_micro_ NaN NaN \n", - "259 elmo-ortho _clean_micro_ NaN NaN \n", - "260 glove _clean_micro_ NaN NaN \n", - "261 openai-cat _clean_micro_ NaN NaN \n", - "262 openai-lex _clean_micro_ NaN NaN \n", - "263 openai-mix _clean_micro_ NaN NaN \n", - "264 bert-base-uncased-lex _clean_micro_ NaN NaN \n", - "265 bert-large-uncased-lex _clean_micro_ NaN NaN \n", - "266 elmo-chars _clean_micro_ NaN NaN \n", - "267 glove _clean_micro_ NaN NaN \n", - "268 openai-lex _clean_micro_ NaN NaN \n", - "\n", - " run task \\\n", - "0 /nfs/jsalt/home/iftenney/exp/edges-20180921-op... coref-ontonotes-conll \n", - "1 /nfs/jsalt/home/iftenney/exp/edges-20180921-op... coref-ontonotes-conll \n", - "2 /nfs/jsalt/home/iftenney/exp/edges-20180922-op... coref-ontonotes-conll \n", - "3 /nfs/jsalt/home/iftenney/exp/final_20180927/ba... coref-ontonotes-conll \n", - "4 /nfs/jsalt/home/iftenney/exp/final_20180927/ba... coref-ontonotes-conll \n", - "5 /nfs/jsalt/home/iftenney/exp/final_20180927/ba... coref-ontonotes-conll \n", - "6 /nfs/jsalt/home/iftenney/exp/final_20180927/ba... coref-ontonotes-conll \n", - "7 /nfs/jsalt/home/iftenney/exp/final_20180927/ba... coref-ontonotes-conll \n", - "8 /nfs/jsalt/exp/edges-20190124-bert/bert-base-u... coref-ontonotes-conll \n", - "9 /nfs/jsalt/exp/edges-20190124-bert/bert-base-u... coref-ontonotes-conll \n", - "10 /nfs/jsalt/exp/edges-20190125-bert-large/bert-... coref-ontonotes-conll \n", - "11 /nfs/jsalt/exp/edges-20190125-bert-large/bert-... coref-ontonotes-conll \n", - "12 /nfs/jsalt/exp/edges-20190129-bert-mix/bert-ba... coref-ontonotes-conll \n", - "13 /nfs/jsalt/exp/edges-20190129-bert-mix/bert-la... coref-ontonotes-conll \n", - "14 /nfs/jsalt/exp/edges-20190209-openai-mix/opena... coref-ontonotes-conll \n", - "15 /nfs/jsalt/exp/edges-20190220-core-bow/bert-ba... coref-ontonotes-conll \n", - "16 /nfs/jsalt/exp/edges-20190220-core-bow/bert-la... coref-ontonotes-conll \n", - "17 /nfs/jsalt/exp/edges-20190220-core-bow/elmo-ch... coref-ontonotes-conll \n", - "18 /nfs/jsalt/exp/edges-20190220-core-bow/glove-e... coref-ontonotes-conll \n", - "19 /nfs/jsalt/exp/edges-20190220-core-bow/openai-... coref-ontonotes-conll \n", - "20 /nfs/jsalt/home/iftenney/exp/final_20180927/cn... coref-ontonotes-conll \n", - "21 /nfs/jsalt/home/iftenney/exp/final_20180927/cn... coref-ontonotes-conll \n", - "22 /nfs/jsalt/home/iftenney/exp/edges-20180921-op... dep-labeling-ewt \n", - "23 /nfs/jsalt/home/iftenney/exp/edges-20180921-op... dep-labeling-ewt \n", - "24 /nfs/jsalt/home/iftenney/exp/edges-20180922-op... dep-labeling-ewt \n", - "25 /nfs/jsalt/home/iftenney/exp/final_20180927/ba... dep-labeling-ewt \n", - "26 /nfs/jsalt/home/iftenney/exp/final_20180927/ba... dep-labeling-ewt \n", - "27 /nfs/jsalt/home/iftenney/exp/final_20180927/ba... dep-labeling-ewt \n", - "28 /nfs/jsalt/home/iftenney/exp/final_20180927/ba... dep-labeling-ewt \n", - "29 /nfs/jsalt/home/iftenney/exp/final_20180927/ba... dep-labeling-ewt \n", - ".. ... ... \n", - "239 /nfs/jsalt/exp/edges-20190205-tacred/elmo-full... rel-tacred \n", - "240 /nfs/jsalt/exp/edges-20190205-tacred/elmo-orth... rel-tacred \n", - "241 /nfs/jsalt/exp/edges-20190205-tacred/glove-edg... rel-tacred \n", - "242 /nfs/jsalt/exp/edges-20190205-tacred/openai-ca... rel-tacred \n", - "243 /nfs/jsalt/exp/edges-20190205-tacred/openai-le... rel-tacred \n", - "244 /nfs/jsalt/exp/edges-20190209-openai-mix/opena... rel-tacred \n", - "245 /nfs/jsalt/exp/edges-20190220-rel-bow//bert-ba... rel-tacred \n", - "246 /nfs/jsalt/exp/edges-20190220-rel-bow//bert-la... rel-tacred \n", - "247 /nfs/jsalt/exp/edges-20190220-rel-bow//elmo-ch... rel-tacred \n", - "248 /nfs/jsalt/exp/edges-20190220-rel-bow//glove-e... rel-tacred \n", - "249 /nfs/jsalt/exp/edges-20190220-rel-bow//openai-... rel-tacred \n", - "250 /nfs/jsalt/exp/edges-20190205-semeval/bert-bas... rel-semeval \n", - "251 /nfs/jsalt/exp/edges-20190205-semeval/bert-bas... rel-semeval \n", - "252 /nfs/jsalt/exp/edges-20190205-semeval/bert-bas... rel-semeval \n", - "253 /nfs/jsalt/exp/edges-20190205-semeval/bert-lar... rel-semeval \n", - "254 /nfs/jsalt/exp/edges-20190205-semeval/bert-lar... rel-semeval \n", - "255 /nfs/jsalt/exp/edges-20190205-semeval/bert-lar... rel-semeval \n", - "256 /nfs/jsalt/exp/edges-20190205-semeval/cove-edg... rel-semeval \n", - "257 /nfs/jsalt/exp/edges-20190205-semeval/elmo-cha... rel-semeval \n", - "258 /nfs/jsalt/exp/edges-20190205-semeval/elmo-ful... rel-semeval \n", - "259 /nfs/jsalt/exp/edges-20190205-semeval/elmo-ort... rel-semeval \n", - "260 /nfs/jsalt/exp/edges-20190205-semeval/glove-ed... rel-semeval \n", - "261 /nfs/jsalt/exp/edges-20190205-semeval/openai-c... rel-semeval \n", - "262 /nfs/jsalt/exp/edges-20190205-semeval/openai-l... rel-semeval \n", - "263 /nfs/jsalt/exp/edges-20190209-openai-mix/opena... rel-semeval \n", - "264 /nfs/jsalt/exp/edges-20190220-rel-bow//bert-ba... rel-semeval \n", - "265 /nfs/jsalt/exp/edges-20190220-rel-bow//bert-la... rel-semeval \n", - "266 /nfs/jsalt/exp/edges-20190220-rel-bow//elmo-ch... rel-semeval \n", - "267 /nfs/jsalt/exp/edges-20190220-rel-bow//glove-e... rel-semeval \n", - "268 /nfs/jsalt/exp/edges-20190220-rel-bow//openai-... rel-semeval \n", - "\n", - " split ... precision recall f1_score \\\n", - "0 val ... 0.855263 0.817258 0.835829 \n", - "1 val ... 0.808771 0.660696 0.727273 \n", - "2 val ... 0.855844 0.810885 0.832758 \n", - "3 val ... 0.835032 0.761970 0.796830 \n", - "4 val ... 0.802593 0.714261 0.755855 \n", - "5 val ... 0.861156 0.834309 0.847520 \n", - "6 val ... 0.812175 0.781261 0.796418 \n", - "7 val ... 0.793172 0.684292 0.734720 \n", - "8 val ... 0.892236 0.892697 0.892467 \n", - "9 val ... 0.797980 0.721151 0.757622 \n", - "10 val ... 0.894575 0.903204 0.898869 \n", - "11 val ... 0.803609 0.720978 0.760054 \n", - "12 val ... 0.905996 0.903031 0.904511 \n", - "13 val ... 0.920096 0.924216 0.922152 \n", - "14 val ... 0.861145 0.863073 0.862108 \n", - "15 val ... 0.802081 0.756631 0.778694 \n", - "16 val ... 0.804084 0.752842 0.777620 \n", - "17 val ... 0.808431 0.746469 0.776216 \n", - "18 val ... 0.808152 0.734240 0.769425 \n", - "19 val ... 0.820021 0.670169 0.737560 \n", - "20 val ... 0.824132 0.776438 0.799574 \n", - "21 val ... 0.826167 0.774371 0.799431 \n", - "22 val ... 0.937647 0.904301 0.920672 \n", - "23 val ... 0.887963 0.691557 0.777549 \n", - "24 val ... 0.938856 0.905018 0.921626 \n", - "25 val ... 0.924871 0.878057 0.900856 \n", - "26 val ... 0.898903 0.730864 0.806221 \n", - "27 val ... 0.957174 0.927479 0.942093 \n", - "28 val ... 0.912583 0.800319 0.852772 \n", - "29 val ... 0.899781 0.671485 0.769048 \n", - ".. ... ... ... ... ... \n", - "239 val ... 0.705402 0.413171 0.521114 \n", - "240 val ... 0.614417 0.233628 0.338531 \n", - "241 val ... 0.612549 0.174209 0.271269 \n", - "242 val ... 0.707666 0.309051 0.430218 \n", - "243 val ... 0.579454 0.132818 0.216103 \n", - "244 val ... 0.682254 0.327447 0.442511 \n", - "245 val ... 0.646013 0.247425 0.357808 \n", - "246 val ... 0.650498 0.180096 0.282092 \n", - "247 val ... 0.639163 0.286424 0.395579 \n", - "248 val ... 0.635789 0.258830 0.367891 \n", - "249 val ... 0.617951 0.241906 0.347700 \n", - "250 val ... 0.891473 0.718002 0.795389 \n", - "251 val ... 0.754653 0.464100 0.574742 \n", - "252 val ... 0.891667 0.779396 0.831760 \n", - "253 val ... 0.876448 0.708637 0.783659 \n", - "254 val ... 0.757774 0.481790 0.589059 \n", - "255 val ... 0.894366 0.792924 0.840596 \n", - "256 val ... 0.871693 0.685744 0.767618 \n", - "257 val ... 0.704274 0.428720 0.532988 \n", - "258 val ... 0.869001 0.697190 0.773672 \n", - "259 val ... 0.744863 0.452653 0.563107 \n", - "260 val ... 0.780847 0.441207 0.563830 \n", - "261 val ... 0.871043 0.773153 0.819184 \n", - "262 val ... 0.765000 0.477627 0.588085 \n", - "263 val ... 0.855056 0.791883 0.822258 \n", - "264 val ... 0.813738 0.640999 0.717113 \n", - "265 val ... 0.786260 0.643080 0.707499 \n", - "266 val ... 0.802372 0.633715 0.708140 \n", - "267 val ... 0.806242 0.645161 0.716763 \n", - "268 val ... 0.825166 0.648283 0.726107 \n", - "\n", - " accuracy_errn95 precision_errn95 recall_errn95 f1_errn95 score \\\n", - "0 0.003098 0.009258 0.009941 0.009587 0.835829 \n", - "1 0.003768 0.011192 0.012179 0.011665 0.727273 \n", - "2 0.003118 0.009282 0.010073 0.009661 0.832758 \n", - "3 0.003380 0.009994 0.010955 0.010452 0.796830 \n", - "4 0.003651 0.010853 0.011621 0.011224 0.755855 \n", - "5 0.003003 0.009036 0.009564 0.009293 0.847520 \n", - "6 0.003423 0.010243 0.010634 0.010435 0.796418 \n", - "7 0.003763 0.011217 0.011956 0.011575 0.734720 \n", - "8 0.002567 0.007974 0.007961 0.007968 0.892467 \n", - "9 0.003651 0.010864 0.011535 0.011189 0.757622 \n", - "10 0.002499 0.007862 0.007606 0.007732 0.898869 \n", - "11 0.003629 0.010789 0.011537 0.011150 0.760054 \n", - "12 0.002424 0.007519 0.007612 0.007565 0.904511 \n", - "13 0.002201 0.006959 0.006808 0.006882 0.922152 \n", - "14 0.002888 0.008885 0.008843 0.008864 0.862108 \n", - "15 0.003539 0.010552 0.011038 0.010790 0.778694 \n", - "16 0.003541 0.010551 0.011096 0.010817 0.777620 \n", - "17 0.003540 0.010535 0.011190 0.010853 0.776216 \n", - "18 0.003575 0.010626 0.011363 0.010982 0.769425 \n", - "19 0.003705 0.010931 0.012094 0.011483 0.737560 \n", - "20 0.003383 0.010089 0.010717 0.010394 0.799574 \n", - "21 0.003380 0.010069 0.010752 0.010399 0.799431 \n", - "22 0.000098 0.003045 0.003639 0.003316 0.920672 \n", - "23 0.000155 0.004421 0.005713 0.004984 0.777549 \n", - "24 0.000097 0.003018 0.003626 0.003295 0.921626 \n", - "25 0.000109 0.003346 0.004047 0.003664 0.900856 \n", - "26 0.000146 0.004135 0.005486 0.004716 0.806221 \n", - "27 0.000083 0.002544 0.003208 0.002838 0.942093 \n", - "28 0.000130 0.003731 0.004945 0.004253 0.852772 \n", - "29 0.000156 0.004300 0.005809 0.004942 0.769048 \n", - ".. ... ... ... ... ... \n", - "239 0.000135 0.015834 0.013090 0.014332 0.521114 \n", - "240 0.000148 0.020983 0.011249 0.014646 0.338531 \n", - "241 0.000150 0.024285 0.010083 0.014249 0.271269 \n", - "242 0.000141 0.018297 0.012284 0.014699 0.430218 \n", - "243 0.000152 0.027410 0.009022 0.013576 0.216103 \n", - "244 0.000141 0.017866 0.012475 0.014692 0.442511 \n", - "245 0.000146 0.020541 0.011471 0.014721 0.357808 \n", - "246 0.000149 0.024090 0.010215 0.014347 0.282092 \n", - "247 0.000145 0.019071 0.012018 0.014745 0.395579 \n", - "248 0.000146 0.020049 0.011643 0.014732 0.367891 \n", - "249 0.000148 0.020645 0.011384 0.014676 0.347700 \n", - "250 0.001770 0.021913 0.028450 0.024757 0.795389 \n", - "251 0.002395 0.034692 0.031531 0.033036 0.574742 \n", - "252 0.001637 0.021018 0.026217 0.023332 0.831760 \n", - "253 0.001821 0.023138 0.028729 0.025632 0.783659 \n", - "254 0.002371 0.033972 0.031592 0.032739 0.589059 \n", - "255 0.001600 0.020639 0.025620 0.022861 0.840596 \n", - "256 0.001875 0.023840 0.029351 0.026310 0.767618 \n", - "257 0.002502 0.036982 0.031290 0.033899 0.532988 \n", - "258 0.001858 0.023816 0.029051 0.026174 0.773672 \n", - "259 0.002422 0.035357 0.031471 0.033301 0.563107 \n", - "260 0.002388 0.034795 0.031394 0.033007 0.563830 \n", - "261 0.001703 0.022492 0.026479 0.024323 0.819184 \n", - "262 0.002365 0.033927 0.031581 0.032712 0.588085 \n", - "263 0.001705 0.023129 0.025667 0.024332 0.822258 \n", - "264 0.002065 0.027734 0.030330 0.028974 0.717113 \n", - "265 0.002116 0.028660 0.030291 0.029453 0.707499 \n", - "266 0.002097 0.028330 0.030461 0.029357 0.708140 \n", - "267 0.002073 0.027935 0.030251 0.029047 0.716763 \n", - "268 0.002031 0.027094 0.030191 0.028558 0.726107 \n", - "\n", - " score_errn95 display_row \n", - "0 0.009587 coref-ontonotes-conll-1 \n", - "1 0.011665 coref-ontonotes-conll-1 \n", - "2 0.009661 coref-ontonotes-conll-1 \n", - "3 0.010452 coref-ontonotes-conll-1 \n", - "4 0.011224 coref-ontonotes-conll-1 \n", - "5 0.009293 coref-ontonotes-conll-1 \n", - "6 0.010435 coref-ontonotes-conll-1 \n", - "7 0.011575 coref-ontonotes-conll-1 \n", - "8 0.007968 coref-ontonotes-conll-1 \n", - "9 0.011189 coref-ontonotes-conll-1 \n", - "10 0.007732 coref-ontonotes-conll-1 \n", - "11 0.011150 coref-ontonotes-conll-1 \n", - "12 0.007565 coref-ontonotes-conll-1 \n", - "13 0.006882 coref-ontonotes-conll-1 \n", - "14 0.008864 coref-ontonotes-conll-1 \n", - "15 0.010790 coref-ontonotes-conll-1 \n", - "16 0.010817 coref-ontonotes-conll-1 \n", - "17 0.010853 coref-ontonotes-conll-1 \n", - "18 0.010982 coref-ontonotes-conll-1 \n", - "19 0.011483 coref-ontonotes-conll-1 \n", - "20 0.010394 coref-ontonotes-conll-1 \n", - "21 0.010399 coref-ontonotes-conll-1 \n", - "22 0.003316 dep-labeling-ewt-_micro_avg_ \n", - "23 0.004984 dep-labeling-ewt-_micro_avg_ \n", - "24 0.003295 dep-labeling-ewt-_micro_avg_ \n", - "25 0.003664 dep-labeling-ewt-_micro_avg_ \n", - "26 0.004716 dep-labeling-ewt-_micro_avg_ \n", - "27 0.002838 dep-labeling-ewt-_micro_avg_ \n", - "28 0.004253 dep-labeling-ewt-_micro_avg_ \n", - "29 0.004942 dep-labeling-ewt-_micro_avg_ \n", - ".. ... ... \n", - "239 0.014332 rel-tacred-_clean_micro_ \n", - "240 0.014646 rel-tacred-_clean_micro_ \n", - "241 0.014249 rel-tacred-_clean_micro_ \n", - "242 0.014699 rel-tacred-_clean_micro_ \n", - "243 0.013576 rel-tacred-_clean_micro_ \n", - "244 0.014692 rel-tacred-_clean_micro_ \n", - "245 0.014721 rel-tacred-_clean_micro_ \n", - "246 0.014347 rel-tacred-_clean_micro_ \n", - "247 0.014745 rel-tacred-_clean_micro_ \n", - "248 0.014732 rel-tacred-_clean_micro_ \n", - "249 0.014676 rel-tacred-_clean_micro_ \n", - "250 0.024757 rel-semeval-_clean_micro_ \n", - "251 0.033036 rel-semeval-_clean_micro_ \n", - "252 0.023332 rel-semeval-_clean_micro_ \n", - "253 0.025632 rel-semeval-_clean_micro_ \n", - "254 0.032739 rel-semeval-_clean_micro_ \n", - "255 0.022861 rel-semeval-_clean_micro_ \n", - "256 0.026310 rel-semeval-_clean_micro_ \n", - "257 0.033899 rel-semeval-_clean_micro_ \n", - "258 0.026174 rel-semeval-_clean_micro_ \n", - "259 0.033301 rel-semeval-_clean_micro_ \n", - "260 0.033007 rel-semeval-_clean_micro_ \n", - "261 0.024323 rel-semeval-_clean_micro_ \n", - "262 0.032712 rel-semeval-_clean_micro_ \n", - "263 0.024332 rel-semeval-_clean_micro_ \n", - "264 0.028974 rel-semeval-_clean_micro_ \n", - "265 0.029453 rel-semeval-_clean_micro_ \n", - "266 0.029357 rel-semeval-_clean_micro_ \n", - "267 0.029047 rel-semeval-_clean_micro_ \n", - "268 0.028558 rel-semeval-_clean_micro_ \n", - "\n", - "[269 rows x 31 columns]" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# SPLIT = \"test\"\n", - "SPLIT = \"val\"\n", - "mask = df['split'] == SPLIT\n", - "mask &= (df['exp_type'] != \"openai\")\n", - "mask &= df['exp_type'].map(lambda s: '-cased-' not in s) # skip cased BERT for now\n", - "mask &= (df['task'] != 'dpr') | df['seed'].notnull() # only use folds for DPR\n", - "# Skip these tasks\n", - "mask &= (df['task'] != \"constituent-ontonotes\")\n", - "mask &= (df['task'] != \"ner-tacred\")\n", - "mask &= (df['task'] != \"coref-gap\")\n", - "mask &= (df['task'] != \"coref-gap-ontonotes\")\n", - "mask &= (df['task'] != \"noun-verb\")\n", - "# mask &= (df['task'] != \"rel-tacred\")\n", - "# mask &= (df['task'] != \"rel-semeval\")\n", - "\n", - "final_scores = []\n", - "for task in df['task'].unique():\n", - " task_scores = df[mask & (df['task'] == task)]\n", - " if is_coref_task(task):\n", - " final_scores.append(task_scores[task_scores['label'] == \"1\"])\n", - " # For GAP coref, have stratified by gender\n", - " if task.startswith(\"coref-gap\"):\n", - " final_scores.append(task_scores[task_scores['label'] == \"_info.pronoun_gender_MASCULINE_1_\"])\n", - " final_scores.append(task_scores[task_scores['label'] == \"_info.pronoun_gender_FEMININE_1_\"])\n", - " elif task == \"dpr\":\n", - " dpr_mask = task_scores['seed'] == \"_mean_\"\n", - " dpr_mask &= task_scores['label'] == \"_micro_avg_\"\n", - " final_scores.append(task_scores[dpr_mask])\n", - " elif is_srl_task(task):\n", - " final_scores.append(task_scores[task_scores['label'] == '_core_'])\n", - " final_scores.append(task_scores[task_scores['label'] == '_non_core_'])\n", - " # Use clean version, average only over core or noncore roles.\n", - " final_scores.append(task_scores[task_scores['label'] == '_clean_micro_'])\n", - " elif is_constituent_task(task):\n", - " final_scores.append(task_scores[task_scores['label'] == '_pos_'])\n", - " final_scores.append(task_scores[task_scores['label'] == '_nonterminal_'])\n", - " final_scores.append(task_scores[task_scores['label'] == '_micro_avg_'])\n", - " elif is_relation_task(task):\n", - " # Relation tasks include specific \"no_relation\" label\n", - " final_scores.append(task_scores[task_scores['label'] == '_clean_micro_'])\n", - " elif task == \"noun-verb\":\n", - " # Noun-verb reports accuracy on VERB class\n", - " final_scores.append(task_scores[task_scores['label'] == 'VERB'])\n", - " else:\n", - " final_scores.append(task_scores[task_scores['label'] == '_micro_avg_'])\n", - " \n", - "fdf = pd.concat(final_scores, axis=0, ignore_index=True, sort=False)\n", - "# fdf['task_and_metric'] = [\"%s-%s\" % tl for tl in zip(fdf.task, fdf.label)]\n", - "def format_display_row(task, label, seed):\n", - " ret = f\"{task}-{label}\"\n", - " if seed:\n", - " ret += f\":{seed}\"\n", - " return ret\n", - "\n", - "fdf['display_row'] = [format_display_row(*args) for args in zip(fdf.task, fdf.label, fdf.seed)]\n", - "print(len(fdf))\n", - "fdf" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Make Table 2 (model comparison)\n", - "\n", - "This should get us 90% of the way there with formatting." - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": { - "scrolled": false - }, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
BERT (base)BERT (large)
F1 ScoreAbs. $\\Delta$F1 ScoreAbs. $\\Delta$
Lex.\\texttt{cat}\\texttt{mix}ELMoLex.\\texttt{cat}\\texttt{mix}(base)ELMo
Part-of-Speech88.3\\textbf{96.8}96.5-0.188.096.3\\textbf{96.6}0.20.0
Constituents66.983.586.61.967.879.6\\textbf{86.9}0.42.2
Dependencies80.293.495.41.280.392.1\\textbf{95.6}0.31.4
Entities89.795.996.00.890.796.0\\textbf{96.5}0.41.2
SRL (all)74.089.090.91.175.187.7\\textbf{92.0}1.02.1
\\quad Core roles\\textit{73.3}\\textit{90.7}\\textit{93.0}\\textit{0.8}\\textit{74.5}\\textit{89.2}\\textbf{\\textit{94.1}}\\textit{1.1}\\textit{1.9}
\\quad Non-core roles\\textit{76.0}\\textit{84.6}\\textit{85.8}\\textit{1.6}\\textit{76.4}\\textit{83.9}\\textbf{\\textit{86.8}}\\textit{1.0}\\textit{2.6}
OntoNotes coref.75.889.290.55.776.089.9\\textbf{92.2}1.87.5
SPR176.783.3\\textbf{84.0}1.176.782.3\\textbf{83.7}-0.30.7
SPR280.4\\textbf{82.6}\\textbf{82.8}0.380.582.3\\textbf{82.9}0.10.4
Winograd coref.53.954.955.91.353.654.5\\textbf{61.8}5.87.1
Rel. (TACRED)20.048.4\\textbf{52.2}0.026.748.1\\textbf{51.9}-0.2-0.2
Rel. (SemEval)57.579.583.25.858.978.4\\textbf{84.1}0.96.7
\\midrule Macro Average69.481.583.11.770.480.6\\textbf{84.0}0.92.7
\n", - "
" - ], - "text/plain": [ - " BERT (base) \\\n", - " F1 Score \n", - " Lex. \\texttt{cat} \\texttt{mix} \n", - "Part-of-Speech 88.3 \\textbf{96.8} 96.5 \n", - "Constituents 66.9 83.5 86.6 \n", - "Dependencies 80.2 93.4 95.4 \n", - "Entities 89.7 95.9 96.0 \n", - "SRL (all) 74.0 89.0 90.9 \n", - "\\quad Core roles \\textit{73.3} \\textit{90.7} \\textit{93.0} \n", - "\\quad Non-core roles \\textit{76.0} \\textit{84.6} \\textit{85.8} \n", - "OntoNotes coref. 75.8 89.2 90.5 \n", - "SPR1 76.7 83.3 \\textbf{84.0} \n", - "SPR2 80.4 \\textbf{82.6} \\textbf{82.8} \n", - "Winograd coref. 53.9 54.9 55.9 \n", - "Rel. (TACRED) 20.0 48.4 \\textbf{52.2} \n", - "Rel. (SemEval) 57.5 79.5 83.2 \n", - "\\midrule Macro Average 69.4 81.5 83.1 \n", - "\n", - " BERT (large) \\\n", - " Abs. $\\Delta$ F1 Score \n", - " ELMo Lex. \\texttt{cat} \n", - "Part-of-Speech -0.1 88.0 96.3 \n", - "Constituents 1.9 67.8 79.6 \n", - "Dependencies 1.2 80.3 92.1 \n", - "Entities 0.8 90.7 96.0 \n", - "SRL (all) 1.1 75.1 87.7 \n", - "\\quad Core roles \\textit{0.8} \\textit{74.5} \\textit{89.2} \n", - "\\quad Non-core roles \\textit{1.6} \\textit{76.4} \\textit{83.9} \n", - "OntoNotes coref. 5.7 76.0 89.9 \n", - "SPR1 1.1 76.7 82.3 \n", - "SPR2 0.3 80.5 82.3 \n", - "Winograd coref. 1.3 53.6 54.5 \n", - "Rel. (TACRED) 0.0 26.7 48.1 \n", - "Rel. (SemEval) 5.8 58.9 78.4 \n", - "\\midrule Macro Average 1.7 70.4 80.6 \n", - "\n", - " \n", - " Abs. $\\Delta$ \n", - " \\texttt{mix} (base) ELMo \n", - "Part-of-Speech \\textbf{96.6} 0.2 0.0 \n", - "Constituents \\textbf{86.9} 0.4 2.2 \n", - "Dependencies \\textbf{95.6} 0.3 1.4 \n", - "Entities \\textbf{96.5} 0.4 1.2 \n", - "SRL (all) \\textbf{92.0} 1.0 2.1 \n", - "\\quad Core roles \\textbf{\\textit{94.1}} \\textit{1.1} \\textit{1.9} \n", - "\\quad Non-core roles \\textbf{\\textit{86.8}} \\textit{1.0} \\textit{2.6} \n", - "OntoNotes coref. \\textbf{92.2} 1.8 7.5 \n", - "SPR1 \\textbf{83.7} -0.3 0.7 \n", - "SPR2 \\textbf{82.9} 0.1 0.4 \n", - "Winograd coref. \\textbf{61.8} 5.8 7.1 \n", - "Rel. (TACRED) \\textbf{51.9} -0.2 -0.2 \n", - "Rel. (SemEval) \\textbf{84.1} 0.9 6.7 \n", - "\\midrule Macro Average \\textbf{84.0} 0.9 2.7 " - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\\begin{tabular}{@{}l|cccr|cccrr@{}}\n", - "\\toprule\n", - "{} & \\multicolumn{4}{c}{\\textbf{BERT (base)}} & \\multicolumn{5}{c}{\\textbf{BERT (large)}} \\\\\n", - "{} & \\multicolumn{3}{c}{\\textbf{F1 Score}} & \\textbf{Abs. $\\Delta$} & \\multicolumn{3}{c}{\\textbf{F1 Score}} & \\multicolumn{2}{c}{\\textbf{Abs. $\\Delta$}} \\\\\n", - "{} & \\textbf{Lex.} & \\textbf{\\texttt{cat}} & \\textbf{\\texttt{mix}} & \\textbf{ELMo} & \\textbf{Lex.} & \\textbf{\\texttt{cat}} & \\textbf{\\texttt{mix}} & \\textbf{(base)} & \\textbf{ELMo} \\\\\n", - "\\midrule\n", - "Part-of-Speech & 88.3 & \\textbf{96.8} & 96.5 & -0.1 & 88.0 & 96.3 & \\textbf{96.6} & 0.2 & 0.0 \\\\\n", - "Constituents & 66.9 & 83.5 & 86.6 & 1.9 & 67.8 & 79.6 & \\textbf{86.9} & 0.4 & 2.2 \\\\\n", - "Dependencies & 80.2 & 93.4 & 95.4 & 1.2 & 80.3 & 92.1 & \\textbf{95.6} & 0.3 & 1.4 \\\\\n", - "Entities & 89.7 & 95.9 & 96.0 & 0.8 & 90.7 & 96.0 & \\textbf{96.5} & 0.4 & 1.2 \\\\\n", - "SRL (all) & 74.0 & 89.0 & 90.9 & 1.1 & 75.1 & 87.7 & \\textbf{92.0} & 1.0 & 2.1 \\\\\n", - "\\quad Core roles & \\textit{73.3} & \\textit{90.7} & \\textit{93.0} & \\textit{0.8} & \\textit{74.5} & \\textit{89.2} & \\textbf{\\textit{94.1}} & \\textit{1.1} & \\textit{1.9} \\\\\n", - "\\quad Non-core roles & \\textit{76.0} & \\textit{84.6} & \\textit{85.8} & \\textit{1.6} & \\textit{76.4} & \\textit{83.9} & \\textbf{\\textit{86.8}} & \\textit{1.0} & \\textit{2.6} \\\\\n", - "OntoNotes coref. & 75.8 & 89.2 & 90.5 & 5.7 & 76.0 & 89.9 & \\textbf{92.2} & 1.8 & 7.5 \\\\\n", - "SPR1 & 76.7 & 83.3 & \\textbf{84.0} & 1.1 & 76.7 & 82.3 & \\textbf{83.7} & -0.3 & 0.7 \\\\\n", - "SPR2 & 80.4 & \\textbf{82.6} & \\textbf{82.8} & 0.3 & 80.5 & 82.3 & \\textbf{82.9} & 0.1 & 0.4 \\\\\n", - "Winograd coref. & 53.9 & 54.9 & 55.9 & 1.3 & 53.6 & 54.5 & \\textbf{61.8} & 5.8 & 7.1 \\\\\n", - "Rel. (TACRED) & 20.0 & 48.4 & \\textbf{52.2} & 0.0 & 26.7 & 48.1 & \\textbf{51.9} & -0.2 & -0.2 \\\\\n", - "Rel. (SemEval) & 57.5 & 79.5 & 83.2 & 5.8 & 58.9 & 78.4 & \\textbf{84.1} & 0.9 & 6.7 \\\\\n", - "\\midrule Macro Average & 69.4 & 81.5 & 83.1 & 1.7 & 70.4 & 80.6 & \\textbf{84.0} & 0.9 & 2.7 \\\\\n", - "\\bottomrule\n", - "\\end{tabular}\n", - "\n" - ] - } - ], - "source": [ - "# scores and confidence intervals\n", - "sdf = fdf.pivot(index=\"display_row\", columns=\"display_col\", values=\"score\")\n", - "cdf = fdf.pivot(index=\"display_row\", columns=\"display_col\", values=\"score_errn95\")\n", - "\n", - "# Table 2, top part (original table)\n", - "columns = collections.OrderedDict()\n", - "columns[(\"CoVe\", \"Lex.\")] = sdf['glove (base)']\n", - "columns[(\"CoVe\", \"Full\")] = sdf['cove (base)']\n", - "columns[(\"CoVe\", \"Abs. $\\Delta$\")] = sdf['cove (base)'] - sdf['glove (base)']\n", - "columns[(\"ELMo\", \"Lex.\")] = sdf['elmo-chars (base)']\n", - "columns[(\"ELMo\", \"Full\")] = sdf['elmo-full (base)']\n", - "columns[(\"ELMo\", \"Abs. $\\Delta$\")] = sdf['elmo-full (base)'] - sdf['elmo-chars (base)']\n", - "columns[(\"Transformer LM\", \"Lex.\")] = sdf['openai-lex (base)']\n", - "columns[(\"Transformer LM\", \"\\texttt{cat}\")] = sdf['openai-cat (base)']\n", - "# columns[(\"Transformer LM\", \"Abs. $\\Delta$\")] = sdf['openai-cat (base)'] - sdf['openai-lex (base)']\n", - "columns[(\"Transformer LM\", \"\\texttt{mix}\")] = sdf['openai-mix (base)']\n", - "# columns[(\"Transformer LM\", \"Abs. $\\Delta$\")] = sdf['openai-mix (base)'] - sdf['openai-lex (base)']\n", - "COLUMN_FORMAT=\"|ccr|ccr|ccc\"\n", - "# Table 2, bottom part (new results)\n", - "columns = collections.OrderedDict()\n", - "columns[(\"BERT (base)\", \"F1 Score\", \"Lex.\")] = sdf['bert-base-uncased-lex (base)']\n", - "columns[(\"BERT (base)\", \"F1 Score\", \"\\texttt{cat}\")] = sdf['bert-base-uncased-cat (base)']\n", - "columns[(\"BERT (base)\", \"F1 Score\", \"\\texttt{mix}\")] = sdf['bert-base-uncased-mix (base)']\n", - "# columns[(\"BERT (base)\", \"Abs. $\\Delta$\", \"Lex.\")] = sdf['bert-base-uncased-mix (base)'] - sdf['bert-base-uncased-lex (base)']\n", - "columns[(\"BERT (base)\", \"Abs. $\\Delta$\", \"ELMo\")] = sdf['bert-base-uncased-mix (base)'] - sdf['elmo-full (base)']\n", - "columns[(\"BERT (large)\", \"F1 Score\", \"Lex.\")] = sdf['bert-large-uncased-lex (base)']\n", - "columns[(\"BERT (large)\", \"F1 Score\", \"\\texttt{cat}\")] = sdf['bert-large-uncased-cat (base)']\n", - "columns[(\"BERT (large)\", \"F1 Score\", \"\\texttt{mix}\")] = sdf['bert-large-uncased-mix (base)']\n", - "# columns[(\"BERT (large)\", \"Abs. $\\Delta$\", \"Lex.\")] = sdf['bert-large-uncased-mix (base)'] - sdf['bert-large-uncased-lex (base)']\n", - "columns[(\"BERT (large)\", \"Abs. $\\Delta$\", \"(base)\")] = sdf['bert-large-uncased-mix (base)'] - sdf['bert-base-uncased-mix (base)']\n", - "columns[(\"BERT (large)\", \"Abs. $\\Delta$\", \"ELMo\")] = sdf['bert-large-uncased-mix (base)'] - sdf['elmo-full (base)']\n", - "COLUMN_FORMAT=\"|cccr|cccrr\"\n", - "\n", - "# Make a DataFrame that looks like the LaTeX table.\n", - "pdf = pd.DataFrame(columns)\n", - "pdf = pdf.reindex(sorted(pdf.index, key=task_sort_key), axis=0)\n", - "\n", - "# Compute macro average as series, with entries for each column\n", - "def _is_core_task(row):\n", - " return not re.match(r'.*-_(non_)?core_$', row)\n", - "core_task_mask = list(pdf.index.map(_is_core_task))\n", - "macro_average = pdf[core_task_mask].mean()\n", - "macro_average.name = \"Macro Average\"\n", - "\n", - "pdf.index = [_make_display_name(*row.rsplit(\"-\", 1)) for row in pdf.index]\n", - "pdf = pdf.append(macro_average)\n", - "\n", - "# Get row maxima\n", - "maxima = {}\n", - "score_cols = [c for c in pdf.columns if not \"Delta\" in c[1]]\n", - "for row in pdf.index:\n", - " maxima[row] = pdf.loc[row, score_cols].max()\n", - "\n", - "# Format all numbers into strings\n", - "# _format_score_col = lambda f: \"{:.0f}\".format(100*f)\n", - "_format_score_col = lambda f: \"{:.1f}\".format(100*f)\n", - "_format_delta_col = lambda f: \"{:.1f}\".format(100*f)\n", - "# def _get_margin_percent(row):\n", - "# if row.startswith(\"Winograd\"):\n", - "# return 3\n", - "# elif row.startswith(\"SPR\"):\n", - "# return 1\n", - "# else:\n", - "# return 0.5\n", - "def _get_margin_percent(row):\n", - " if row.startswith(\"Winograd\"):\n", - " return 1.5\n", - " elif row.startswith(\"SPR\"):\n", - " return 0.5\n", - " else:\n", - " return 0.25\n", - "\n", - "\n", - "def _format_cell(i, row, col, val):\n", - " num_val = val\n", - " if \"Delta\" in col[1]:\n", - " val = _format_delta_col(val)\n", - " elif row == \"Macro Average\":\n", - " val = _format_delta_col(val)\n", - " else:\n", - " val = _format_score_col(val)\n", - " if i < len(core_task_mask) and not core_task_mask[i]:\n", - " val = \"\\textit{\" + val + \"}\"\n", - "# if row.startswith(\"Winograd\") and col == (\"BERT (large)\", \"F1 Score\", \"\\texttt{mix}\"):\n", - "# val = val + \" $\\pm$ 6\"\n", - " margin = 0.01 * _get_margin_percent(row)\n", - " if num_val > maxima[row] - margin:\n", - " val = \"\\textbf{\" + val + \"}\"\n", - " return val\n", - " \n", - "for i, row in enumerate(pdf.index):\n", - " for col in pdf.columns:\n", - " pdf.loc[row, col] = _format_cell(i, row, col, pdf.loc[row, col])\n", - " \n", - "# Change some row labels\n", - "def _rename_row(row):\n", - " if row == \"SRL (core)\":\n", - " return \"\\quad Core roles\"\n", - " elif row == \"SRL (non-core)\":\n", - " return \"\\quad Non-core roles\"\n", - " elif row.endswith(\" (mean)\"):\n", - " return row[:-7]\n", - " elif row.startswith(\"Relations \"):\n", - " return \"Rel. \" + row.split(\" \", 1)[1]\n", - " elif row == \"Macro Average\":\n", - " return \"\\midrule \" + row\n", - " else:\n", - " return row\n", - "pdf.index = pdf.index.map(_rename_row)\n", - " \n", - "display(pdf)\n", - " \n", - "# Make columns bold.\n", - "_make_bold = lambda text: \"\\textbf{\" + text + \"}\"\n", - "pdf.columns = pdf.columns.map(lambda c: tuple(map(_make_bold, c)))\n", - "\n", - "tex = pdf.to_latex(column_format=\"@{}l\"+COLUMN_FORMAT+\"@{}\", float_format=\"%.2f\",\n", - " bold_rows=False, escape=False, multicolumn=True, multicolumn_format=\"c\")\n", - "print(tex)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Pivot DataFrame to present each task on a row, and each experiment on a column.\n", - "\n", - "This form is suitable to copy-paste into a spreadsheet." - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": { - "scrolled": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "display_row,glove (base),glove (bow),cove (base),elmo-chars (base),elmo-chars (bow),elmo-chars (cnn1),elmo-chars (cnn2),elmo-ortho (base),elmo-full (base),openai-lex (base),openai-lex (bow),openai-cat (base),openai-mix (base),openai-bwb (base),bert-base-uncased-lex (base),bert-base-uncased-lex (bow),bert-base-uncased-cat (base),bert-base-uncased-mix (base),bert-large-uncased-lex (base),bert-large-uncased-lex (bow),bert-large-uncased-cat (base),bert-large-uncased-mix (base)\n", - "pos-ontonotes-_micro_avg_,85.9228,88.4670,93.9147,90.6979,90.8564,95.7660,96.0406,91.2232,96.6235,88.0053,90.2986,94.6398,94.6746,,88.3494,90.6203,96.7583,96.4810,87.9578,90.7934,96.2727,96.6480\n", - "nonterminal-ontonotes-_micro_avg_,55.1509,58.9663,81.4808,68.7957,72.6901,83.9149,84.7074,71.0830,84.7232,64.3216,66.9262,80.9122,84.1387,,66.9288,70.6040,83.4807,86.5765,67.7886,71.4839,79.6116,86.9384\n", - "dep-labeling-ewt-_micro_avg_,76.9048,79.0899,90.0856,80.6221,80.5477,90.7202,91.7454,85.2772,94.2093,77.7549,79.0374,92.0672,94.0847,92.1626,80.1903,81.6522,93.4106,95.3599,80.2943,81.8894,92.0770,95.6186\n", - "ner-ontonotes-_micro_avg_,89.2697,91.3087,92.0233,91.3526,93.3942,93.4360,93.9312,92.1218,95.2299,87.8648,90.6177,93.2675,92.7911,94.6704,89.7127,92.1164,95.8886,96.0229,90.6850,91.9104,95.9514,96.4726\n", - "srl-conll2012-_clean_micro_,57.1503,59.2388,79.9468,72.9396,74.4974,84.4006,85.9012,77.1182,89.8543,66.2599,68.8229,85.7341,89.2792,86.7214,74.0099,75.6584,88.9823,90.9143,75.0541,76.6083,87.7154,91.9638\n", - "srl-conll2012-_core_,53.5800,56.2619,80.3947,72.3186,73.9859,86.1781,87.9790,77.4224,92.1271,63.4472,66.6411,87.3879,91.3408,88.7786,73.2534,75.5327,90.7377,92.9704,74.5300,76.4915,89.2066,94.0546\n", - "srl-conll2012-_non_core_,65.9205,66.4651,78.8007,74.5405,75.8130,79.8228,80.5576,76.3248,84.1404,73.2789,74.3131,81.5030,84.1322,81.4171,75.9532,75.9820,84.5714,85.7894,76.4225,76.9067,83.9472,86.7640\n", - "coref-ontonotes-conll-1,73.4720,76.9425,79.6830,75.5855,77.6216,79.9574,79.9431,79.6418,84.7520,72.7273,73.7560,83.5829,86.2108,83.2758,75.7622,77.8694,89.2467,90.4511,76.0054,77.7620,89.8869,92.2152\n", - "spr1-_micro_avg_,76.3171,77.3620,79.6920,78.6297,79.1338,79.9119,79.8563,79.4347,82.9550,76.8418,77.2299,81.5752,81.5816,82.9812,76.6975,77.0549,83.3432,84.0343,76.6629,77.1346,82.2582,83.6857\n", - "spr2-_micro_avg_,80.7270,80.9592,81.7515,81.2221,81.3423,80.9878,81.0411,81.4711,82.5456,80.6933,80.5784,82.2470,82.4704,82.4584,80.4497,80.7010,82.6340,82.8195,80.4791,80.6469,82.2516,82.9316\n", - "dpr-_micro_avg_:_mean_,53.2291,,54.3673,54.8296,,,,,54.6406,53.3139,,51.9203,53.3875,,53.9219,,54.9189,55.9095,53.5780,,54.5451,61.7591\n", - "rel-tacred-_clean_micro_,27.1269,36.7891,36.2348,33.1749,39.5579,,,33.8531,52.1114,21.6103,34.7700,43.0218,44.2511,,19.9784,35.7808,48.4036,52.1520,26.6874,28.2092,48.0512,51.9079\n", - "rel-semeval-_clean_micro_,56.3830,71.6763,76.7618,53.2988,70.8140,,,56.3107,77.3672,58.8085,72.6107,81.9184,82.2258,,57.4742,71.7113,79.5389,83.1760,58.9059,70.7499,78.3659,84.0596\n", - "\n" - ] - } - ], - "source": [ - "# Pivot to wide-form for spreadsheet, and sort in (mostly) stable order.\n", - "# mask = fdf['task'].map(lambda s: s.startswith('rel-'))\n", - "sheet_df = fdf.pivot(index=\"display_row\", columns=\"display_col\", values=\"score\")\n", - "sheet_df = sheet_df.reindex(sorted(sheet_df.columns, \n", - " key=exp_type_sort_key), axis=1)\n", - "sheet_df = sheet_df.reindex(sorted(sheet_df.index,\n", - " key=task_sort_key), axis=0)\n", - "# sheet_df\n", - "print((100*sheet_df).to_csv(**csv_args))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Print the same format, but show the 95% confidence intervals for each score." - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "display_row,glove (base),glove (bow),cove (base),elmo-chars (base),elmo-chars (bow),elmo-chars (cnn1),elmo-chars (cnn2),elmo-ortho (base),elmo-full (base),openai-lex (base),openai-lex (bow),openai-cat (base),openai-mix (base),openai-bwb (base),bert-base-uncased-lex (base),bert-base-uncased-lex (bow),bert-base-uncased-cat (base),bert-base-uncased-mix (base),bert-large-uncased-lex (base),bert-large-uncased-lex (bow),bert-large-uncased-cat (base),bert-large-uncased-mix (base)\n", - "pos-ontonotes-_micro_avg_,0.1253,0.1164,0.0850,0.1059,0.1051,0.0732,0.0707,0.1030,0.0656,0.1186,0.1078,0.0819,0.0818,,0.1171,0.1063,0.0644,0.0671,0.1188,0.1054,0.0690,0.0655\n", - "nonterminal-ontonotes-_micro_avg_,0.2055,0.2014,0.1514,0.1847,0.1765,0.1434,0.1403,0.1792,0.1403,0.1925,0.1883,0.1538,0.1424,,0.1881,0.1808,0.1450,0.1325,0.1863,0.1787,0.1577,0.1310\n", - "dep-labeling-ewt-_micro_avg_,0.4942,0.4834,0.3664,0.4716,0.4709,0.3512,0.3322,0.4253,0.2838,0.4984,0.4984,0.3316,0.2898,0.3295,0.4827,0.4704,0.3026,0.2572,0.4828,0.4708,0.3293,0.2510\n", - "ner-ontonotes-_micro_avg_,0.4192,0.3835,0.3631,0.3852,0.3401,0.3371,0.3251,0.3695,0.2918,0.4451,0.3995,0.3406,0.3518,0.3058,0.4156,0.3689,0.2713,0.2670,0.3993,0.3733,0.2694,0.2524\n", - "srl-conll2012-_clean_micro_,0.3616,0.3563,0.2767,0.3114,0.3051,0.2473,0.2378,0.2920,0.2060,0.3368,0.3280,0.2386,0.2114,0.2312,0.3072,0.2991,0.2136,0.1957,0.3028,0.2947,0.2244,0.1858\n", - "srl-conll2012-_core_,0.4373,0.4323,0.3279,0.3744,0.3659,0.2821,0.2662,0.3470,0.2198,0.4103,0.3987,0.2715,0.2293,0.2582,0.3697,0.3577,0.2366,0.2080,0.3627,0.3523,0.2539,0.1931\n", - "srl-conll2012-_non_core_,0.6004,0.5987,0.5049,0.5375,0.5326,0.4939,0.4919,0.5211,0.4595,0.5499,0.5444,0.4787,0.4613,0.4787,0.5289,0.5275,0.4511,0.4389,0.5237,0.5234,0.4557,0.4272\n", - "coref-ontonotes-conll-1,1.1575,1.0982,1.0452,1.1224,1.0853,1.0394,1.0399,1.0435,0.9293,1.1665,1.1483,0.9587,0.8864,0.9661,1.1189,1.0790,0.7968,0.7565,1.1150,1.0817,0.7732,0.6882\n", - "spr1-_micro_avg_,1.0894,1.0670,1.0253,1.0467,1.0372,1.0215,1.0259,1.0209,0.9596,1.0781,1.0702,0.9866,0.9811,0.9538,1.0830,1.0729,0.9486,0.9311,1.0839,1.0719,0.9698,0.9398\n", - "spr2-_micro_avg_,1.1364,1.1320,1.1101,1.1247,1.1216,1.1279,1.1292,1.1167,1.0926,1.1374,1.1407,1.0994,1.0940,1.0948,1.1433,1.1355,1.0878,1.0855,1.1429,1.1389,1.0974,1.0823\n", - "dpr-_micro_avg_:_mean_,0.3909,,1.0124,1.7884,,,,,1.5782,0.5404,,1.1859,0.4801,,1.4254,,0.9413,2.2944,1.0892,,1.1356,6.0849\n", - "rel-tacred-_clean_micro_,1.4249,1.4732,1.4733,1.4582,1.4745,,,1.4646,1.4332,1.3576,1.4676,1.4699,1.4692,,1.3324,1.4721,1.4535,1.4326,1.4172,1.4347,1.4553,1.4330\n", - "rel-semeval-_clean_micro_,3.3007,2.9047,2.6310,3.3899,2.9357,,,3.3301,2.6174,3.2712,2.8558,2.4323,2.4332,,3.3036,2.8974,2.4757,2.3332,3.2739,2.9453,2.5632,2.2861\n", - "\n" - ] - } - ], - "source": [ - "sheet_df = fdf.pivot(index=\"display_row\", columns=\"display_col\", values=\"score_errn95\")\n", - "sheet_df = sheet_df.reindex(sorted(sheet_df.columns, \n", - " key=exp_type_sort_key), axis=1)\n", - "sheet_df = sheet_df.reindex(sorted(sheet_df.index,\n", - " key=task_sort_key), axis=0)\n", - "# sheet_df\n", - "print((100*sheet_df).to_csv(**csv_args))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Plot \"final scores\"\n", - "\n", - "Make ELMo baselines figure / table." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "fdf.columns" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "mask = (fdf.exp_type == \"elmo-chars\") \n", - "mask |= ((fdf.exp_type == \"elmo-ortho\") | (fdf.exp_type == \"elmo-full\")) & (fdf.tag == \"base\")\n", - "plot_df = fdf[mask].copy()\n", - "\n", - "_SCORE_COL=\"f1_score\"\n", - "_ERROR_COL=\"f1_errn95\"\n", - "plot_df['_sort_key'] = plot_df['display_col'].map(task_sort_key)\n", - "plot_df.sort_values(by=\"_sort_key\", axis=0, inplace=True)\n", - "plot_df['_display_name'] = [_make_display_name(*tl) \n", - " for tl in zip(plot_df['task'], plot_df['label'])]\n", - "plot_df['col_key'] = list(zip(plot_df['exp_type'], plot_df['tag']))\n", - "plot_df['fmt_score'] = plot_df[_SCORE_COL].map(\n", - " lambda s: \"{:.0f}\".format(100*s)\n", - ")\n", - "plot_df['_err_upper'] = plot_df[_SCORE_COL] + plot_df[_ERROR_COL]\n", - "plot_df['_err_lower'] = plot_df[_SCORE_COL] - plot_df[_ERROR_COL]\n", - "print(\"Found %s entries\" % len(plot_df))\n", - "# long_ds = bokeh.models.ColumnDataSource(data=plot_df)\n", - "\n", - "ordered_labels = list(reversed(plot_df['_display_name'].unique())) + [\"\"]\n", - "_RP = 0.3\n", - "factor_range = bokeh.models.FactorRange(*ordered_labels, range_padding=_RP,\n", - " range_padding_units='absolute')\n", - "tools = \"save,reset\"\n", - "\n", - "xstart = 20\n", - "xend = 100\n", - "_FONT_SIZE = \"15pt\"\n", - "p = bp.figure(y_range=factor_range, x_range=[xstart, xend],\n", - " height=550, width=1200, tools=tools)\n", - "\n", - "label_kw = dict(text_align=\"center\", text_baseline=\"middle\",\n", - " text_font_size=_FONT_SIZE)\n", - "\n", - "palette = bokeh.palettes.Category20[20]\n", - "col_keys = [\n", - " (\"elmo-chars\", \"base\", \"Lex.\", \"diamond\"),\n", - " (\"elmo-chars\", \"cnn1\", \"CNN1\", \"triangle\"),\n", - " (\"elmo-chars\", \"cnn2\", \"CNN2\", \"inverted_triangle\"),\n", - " (\"elmo-ortho\", \"base\", \"Ortho.\", \"square\"),\n", - " (\"elmo-full\", \"base\", \"Full\", \"circle\"),\n", - "]\n", - "for i,ck in enumerate(col_keys):\n", - " print(ck)\n", - " ds = plot_df[plot_df.col_key == ck[:2]]\n", - " y = ds[\"_display_name\"]\n", - " x = 100*ds[_SCORE_COL]\n", - " e = 100*ds[_ERROR_COL]\n", - " c = palette[2*i]\n", - " cp = palette[2*i+1]\n", - " p.hbar(y=y, left=x-e, right=x+e, height=0.90,\n", - " fill_color=c, fill_alpha=0.5,\n", - " line_color=None, line_width=0)\n", - " p.hbar(y=y, left=x-0.05, right=x+0.05, height=0.90,\n", - " fill_color=\"Black\", fill_alpha=1.0,\n", - " line_color=None, line_width=0)\n", - " p.hbar(y=y, left=0, right=x, height=0.90,\n", - " fill_color=\"Gray\", fill_alpha=0.05,\n", - " line_color=None, line_width=0)\n", - " p.scatter(y=y, x=x, size=12, fill_color=c, legend=ck[2],\n", - " marker=ck[3])\n", - " \n", - " dss = bokeh.models.ColumnDataSource(data=ds)\n", - " lpos = xstart+(0.7+i)*(xend-xstart)/20\n", - " score_labels = bokeh.models.LabelSet(y=\"_display_name\", x=lpos,\n", - " text=\"fmt_score\", source=dss, **label_kw)\n", - " p.add_layout(score_labels)\n", - " cat_label = bokeh.models.Label(y=len(ordered_labels)-1+0.6, x=lpos, text=ck[2], \n", - " angle=np.pi/6, **label_kw)\n", - " p.add_layout(cat_label)\n", - "# error_bars = bokeh.models.Whisker(base=\"_display_name\", upper=\"_err_upper\", lower=\"_err_lower\",\n", - "# source=dss, level=\"glyph\", dimension=\"width\")\n", - "# p.add_layout(error_bars)\n", - " \n", - "\n", - "# p.xaxis.major_label_orientation = 1\n", - "p.xaxis.bounds = (0,100)\n", - "p.yaxis.bounds = (-_RP, 2*len(col_keys)+2)\n", - "p.yaxis.major_label_text_font_size = \"13pt\"\n", - "p.xaxis.major_label_text_font_size = _FONT_SIZE\n", - "p.ygrid.grid_line_alpha = 0\n", - "p.xgrid.grid_line_alpha = 0\n", - "p.xaxis.axis_label = \"F1 Score\"\n", - "p.xaxis.axis_label_text_font_size = _FONT_SIZE\n", - "p.legend.orientation = \"horizontal\"\n", - "p.legend.background_fill_color = None\n", - "p.legend.border_line_color = None\n", - "p.legend.label_text_font_size = _FONT_SIZE\n", - "\n", - "p.min_border = 0\n", - "bp.show(p)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Plot by constituent height, span distance, etc.\n", - "\n", - "Run one of the cells below to populate `plot_df`, and uncomment the corresponding title block." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "df.columns" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "mask = (df.split == \"val\")\n", - "mask &= (df.stratifier == \"info.height\") & (df.task == \"nonterminal-ontonotes\")\n", - "mask &= (((df['exp_type'] == \"elmo-full\") | (df[\"exp_type\"] == \"elmo-ortho\")) & (df['tag'] == \"base\")) | \\\n", - " (df['exp_type'] == \"elmo-chars\")\n", - "plot_df = df[mask].copy()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "mask = (df.split == \"val\")\n", - "mask &= df.stratifier.notnull() & (df.task == \"srl-conll2012\")\n", - "# mask &= ((df['exp_type'] == \"elmo-full\") & (df['tag'] == \"base\")) | \\\n", - "# (df['exp_type'] == \"elmo-chars\")\n", - "mask &= (((df['exp_type'] == \"elmo-full\") | (df[\"exp_type\"] == \"elmo-ortho\")) & (df['tag'] == \"base\")) | \\\n", - " (df['exp_type'] == \"elmo-chars\")\n", - "plot_df = df[mask].copy()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "mask = (df.split == \"val\")\n", - "mask &= df.stratifier.notnull() & (df.task == \"coref-ontonotes-conll\")\n", - "# mask &= ((df['exp_type'] == \"elmo-full\") & (df['tag'] == \"base\")) | \\\n", - "# (df['exp_type'] == \"elmo-chars\")\n", - "mask &= (((df['exp_type'] == \"elmo-full\") | (df[\"exp_type\"] == \"elmo-ortho\")) & (df['tag'] == \"base\")) | \\\n", - " (df['exp_type'] == \"elmo-chars\")\n", - "plot_df = df[mask].copy()" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [], - "source": [ - "mask = (df.split == \"val\")\n", - "mask &= df.stratifier.notnull() & (df.task == \"dep-labeling-ewt\")\n", - "# mask &= ((df['exp_type'] == \"elmo-full\") & (df['tag'] == \"base\")) | \\\n", - "# (df['exp_type'] == \"elmo-chars\")\n", - "mask &= (((df['exp_type'] == \"elmo-full\") | (df[\"exp_type\"] == \"elmo-ortho\")) & (df['tag'] == \"base\")) | \\\n", - " (df['exp_type'] == \"elmo-chars\")\n", - "plot_df = df[mask].copy()" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array(['base', 'bow', 'cnn1', 'cnn2'], dtype=object)" - ] - }, - "execution_count": 16, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plot_df.tag.unique()" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": [ - "(function(root) {\n", - " function embed_document(root) {\n", - " \n", - " var docs_json = {\"2b9ed80b-2ed8-4c88-bc31-0b2e9e229758\":{\"roots\":{\"references\":[{\"attributes\":{\"below\":[{\"id\":\"1012\",\"type\":\"LinearAxis\"}],\"extra_y_ranges\":{\"hist\":{\"id\":\"1203\",\"type\":\"Range1d\"}},\"left\":[{\"id\":\"1017\",\"type\":\"LinearAxis\"}],\"min_border\":0,\"plot_height\":400,\"plot_width\":900,\"renderers\":[{\"id\":\"1012\",\"type\":\"LinearAxis\"},{\"id\":\"1016\",\"type\":\"Grid\"},{\"id\":\"1017\",\"type\":\"LinearAxis\"},{\"id\":\"1021\",\"type\":\"Grid\"},{\"id\":\"1030\",\"type\":\"GlyphRenderer\"},{\"id\":\"1046\",\"type\":\"Legend\"},{\"id\":\"1036\",\"type\":\"GlyphRenderer\"},{\"id\":\"1049\",\"type\":\"Band\"},{\"id\":\"1054\",\"type\":\"GlyphRenderer\"},{\"id\":\"1060\",\"type\":\"GlyphRenderer\"},{\"id\":\"1078\",\"type\":\"Band\"},{\"id\":\"1083\",\"type\":\"GlyphRenderer\"},{\"id\":\"1089\",\"type\":\"GlyphRenderer\"},{\"id\":\"1113\",\"type\":\"Band\"},{\"id\":\"1118\",\"type\":\"GlyphRenderer\"},{\"id\":\"1124\",\"type\":\"GlyphRenderer\"},{\"id\":\"1154\",\"type\":\"Band\"},{\"id\":\"1159\",\"type\":\"GlyphRenderer\"},{\"id\":\"1165\",\"type\":\"GlyphRenderer\"},{\"id\":\"1201\",\"type\":\"Band\"},{\"id\":\"1204\",\"type\":\"LinearAxis\"},{\"id\":\"1208\",\"type\":\"GlyphRenderer\"}],\"right\":[{\"id\":\"1204\",\"type\":\"LinearAxis\"}],\"title\":{\"id\":\"1039\",\"type\":\"Title\"},\"toolbar\":{\"id\":\"1024\",\"type\":\"Toolbar\"},\"x_range\":{\"id\":\"1004\",\"type\":\"Range1d\"},\"x_scale\":{\"id\":\"1008\",\"type\":\"LinearScale\"},\"y_range\":{\"id\":\"1006\",\"type\":\"Range1d\"},\"y_scale\":{\"id\":\"1010\",\"type\":\"LinearScale\"}},\"id\":\"1003\",\"subtype\":\"Figure\",\"type\":\"Plot\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"units\":\"screen\",\"value\":12},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1087\",\"type\":\"Scatter\"},{\"attributes\":{},\"id\":\"1075\",\"type\":\"Selection\"},{\"attributes\":{},\"id\":\"1108\",\"type\":\"Selection\"},{\"attributes\":{\"fill_color\":{\"value\":\"Gray\"},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"units\":\"screen\",\"value\":12},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1059\",\"type\":\"Scatter\"},{\"attributes\":{\"line_alpha\":0.1,\"line_color\":\"#1f77b4\",\"line_width\":2,\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1158\",\"type\":\"Line\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"units\":\"screen\",\"value\":12},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1058\",\"type\":\"Scatter\"},{\"attributes\":{},\"id\":\"1022\",\"type\":\"SaveTool\"},{\"attributes\":{},\"id\":\"1013\",\"type\":\"BasicTicker\"},{\"attributes\":{\"source\":{\"id\":\"1161\",\"type\":\"ColumnDataSource\"}},\"id\":\"1166\",\"type\":\"CDSView\"},{\"attributes\":{\"data_source\":{\"id\":\"1115\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1116\",\"type\":\"Line\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1117\",\"type\":\"Line\"},\"selection_glyph\":null,\"view\":{\"id\":\"1119\",\"type\":\"CDSView\"}},\"id\":\"1118\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"source\":{\"id\":\"1051\",\"type\":\"ColumnDataSource\"}},\"id\":\"1055\",\"type\":\"CDSView\"},{\"attributes\":{\"active_drag\":\"auto\",\"active_inspect\":\"auto\",\"active_multi\":null,\"active_scroll\":\"auto\",\"active_tap\":\"auto\",\"tools\":[{\"id\":\"1022\",\"type\":\"SaveTool\"},{\"id\":\"1023\",\"type\":\"ResetTool\"},{\"id\":\"1210\",\"type\":\"HoverTool\"}]},\"id\":\"1024\",\"type\":\"Toolbar\"},{\"attributes\":{},\"id\":\"1074\",\"type\":\"UnionRenderers\"},{\"attributes\":{},\"id\":\"1195\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"axis_label\":\"Span separation distance (tokens)\",\"axis_label_text_font_size\":{\"value\":\"14pt\"},\"formatter\":{\"id\":\"1040\",\"type\":\"BasicTickFormatter\"},\"major_label_text_font_size\":{\"value\":\"14pt\"},\"plot\":{\"id\":\"1003\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"ticker\":{\"id\":\"1013\",\"type\":\"BasicTicker\"}},\"id\":\"1012\",\"type\":\"LinearAxis\"},{\"attributes\":{\"data_source\":{\"id\":\"1056\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1057\",\"type\":\"Scatter\"},\"hover_glyph\":{\"id\":\"1059\",\"type\":\"Scatter\"},\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1058\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1061\",\"type\":\"CDSView\"}},\"id\":\"1060\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square\"},\"size\":{\"units\":\"screen\",\"value\":12},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1122\",\"type\":\"Scatter\"},{\"attributes\":{},\"id\":\"1196\",\"type\":\"Selection\"},{\"attributes\":{\"data_source\":{\"id\":\"1051\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1052\",\"type\":\"Line\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1053\",\"type\":\"Line\"},\"selection_glyph\":null,\"view\":{\"id\":\"1055\",\"type\":\"CDSView\"}},\"id\":\"1054\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"size\":{\"units\":\"screen\",\"value\":12},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1163\",\"type\":\"Scatter\"},{\"attributes\":{},\"id\":\"1044\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"callback\":null,\"end\":1.05,\"start\":0.4},\"id\":\"1006\",\"type\":\"Range1d\"},{\"attributes\":{\"source\":{\"id\":\"1056\",\"type\":\"ColumnDataSource\"}},\"id\":\"1061\",\"type\":\"CDSView\"},{\"attributes\":{\"base\":{\"field\":\"x\",\"units\":\"data\"},\"fill_color\":{\"value\":\"#c5b0d5\"},\"level\":\"underlay\",\"line_color\":{\"value\":\"#9467bd\"},\"lower\":{\"field\":\"lower\",\"units\":\"data\"},\"plot\":{\"id\":\"1003\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"source\":{\"id\":\"1200\",\"type\":\"ColumnDataSource\"},\"upper\":{\"field\":\"upper\",\"units\":\"data\"}},\"id\":\"1201\",\"type\":\"Band\"},{\"attributes\":{\"fill_color\":{\"value\":\"Gray\"},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"diamond\"},\"size\":{\"units\":\"screen\",\"value\":12},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1035\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_color\":{\"value\":\"Gray\"},\"line_color\":{\"value\":\"#1f77b4\"},\"size\":{\"units\":\"screen\",\"value\":12},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1164\",\"type\":\"Scatter\"},{\"attributes\":{\"data_source\":{\"id\":\"1161\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1162\",\"type\":\"Scatter\"},\"hover_glyph\":{\"id\":\"1164\",\"type\":\"Scatter\"},\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1163\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1166\",\"type\":\"CDSView\"}},\"id\":\"1165\",\"type\":\"GlyphRenderer\"},{\"attributes\":{},\"id\":\"1010\",\"type\":\"LinearScale\"},{\"attributes\":{},\"id\":\"1023\",\"type\":\"ResetTool\"},{\"attributes\":{\"callback\":null,\"data\":{\"x\":[0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0,16.0,17.0,18.0,19.0,20.0,21.0,22.0,23.0,24.0,25.0,26.0,27.0,28.0,29.0,30.0,31.0,32.0,33.0,34.0,35.0,36.0,37.0,38.0,39.0,40.0,41.0,42.0,43.0,44.0,45.0,46.0,47.0,48.0,51.0,54.0,56.0,57.0,60.0,61.0,71.0],\"y\":{\"__ndarray__\":\"XzRVkBTT7T8WptpK/53qP26YRROfUOk/8lNk2Ztg5z8XgsEL7MbmP6+0VlorreU/aoTlnkZY5j9uXd4BR4rmP/FXviSL8ec/41YoboXi5j+AoZqOuUToP8+xRiIgPuo/n+d5nud55j/IpHiBTIrnP9FeQnsJ7eU/YuL9yGm+5j8ZrNAZrNDpPzuxEzuxE+s/WaAFWqAF6j+ZmZmZmZnpP5/ikiFYR+s/AAAAAAAA6D91gynyWTfoP1VVVVVVVe0/2Ymd2Imd6D+bmZmZmZnpP2ijvrNR3+k/z7rBFPms6z+7u7u7u7vrP0dY7mmE5e4/Ka+hvIby6j/UCMs9jbDsPwAAAAAAAPA/VFVVVVVV5T/btm3btm3rPwAAAAAAAPA/AAAAAAAA8D/btm3btm3rPxdddNFFF+0/AAAAAAAA6D8AAAAAAADwP1VVVVVVVeU/AAAAAAAA8D8AAAAAAADwPwAAAAAAAPA/AAAAAAAA8D8AAAAAAADwPwAAAAAAAPA/AAAAAAAA8D8AAAAAAADwPwAAAAAAAPA/AAAAAAAAAAAAAAAAAADwPwAAAAAAAPA/AAAAAAAA8D8AAAAAAADwPw==\",\"dtype\":\"float64\",\"shape\":[56]}},\"selected\":{\"id\":\"1194\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1193\",\"type\":\"UnionRenderers\"}},\"id\":\"1120\",\"type\":\"ColumnDataSource\"},{\"attributes\":{},\"id\":\"1193\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"source\":{\"id\":\"1120\",\"type\":\"ColumnDataSource\"}},\"id\":\"1125\",\"type\":\"CDSView\"},{\"attributes\":{\"callback\":null,\"data\":{\"lower\":{\"__ndarray__\":\"Ckvfq3xa7j8THNkBjKDtPylDPVU96uw/xV9PHQ716j/nYoqDPlDqP5fHqkj/C+g/Vb8+BxDa6D/NXtAa3j3nP2BguBl8YOc/5HXqHFeY5z//W59DP5joPz0z2ebIMOo/xr46/J+T5D+9zG8tyovnP2ZF03fW2uE/C5J3O7R45j8GoHTXfFjoPyPICASRDOk/19ri2TnR5T+m4/SlrzvmP0ChvPYvp+c/wXtUAYxw5D9Od0ufwgHdP8k5OT+2Hus/g5UWWHUn4j9a1nueHFniP4k0aex4kec/fNYNpshn7T8K8qqIpqvmP7j0Ls290+k/cG4py1Xj4j9WrX1xudnnP35D3mC3wtw/AAAAAAAA+P8AAAAAAAD4/wAAAAAAAPj/AAAAAAAA+P/btm3btm3rPwAAAAAAAPj//Tmf1GjX1D8AAAAAAAD4//05n9Ro19Q/AAAAAAAA+P8AAAAAAAD4/wAAAAAAAPj/AAAAAAAA+P8AAAAAAAD4/wAAAAAAAPj/AAAAAAAA+P8AAAAAAAD4/wAAAAAAAPj/AAAAAAAA+P8AAAAAAAD4/wAAAAAAAPj/AAAAAAAA+P8AAAAAAAD4/w==\",\"dtype\":\"float64\",\"shape\":[56]},\"upper\":{\"__ndarray__\":\"2B5FBTya7j8X7sUt5gruP/X67QL4i+0/NSdmUkoG7D97g+gvIMXrP+MK7tNdK+o/44EQZJM56z9tnua3zjPqP8KqoK7Gteo/TLiof7FK6z8xMWPN3CLsP3fiZ9yArO0/9GSzjJtO6j9JZ36pr3nsP3ZxmmPgkuk/p0M8CCxO7D92euzhKrntPwWuWSPlVe4/FdjoVIEb7T9epWEybQzuP/4jaUyA5+4/R64StmQ77T8B7wRbySnsP576ttAXe/A/zVau9nad7D+C/YwsITTuP3hPGfm9CvA/fNYNpshn7T+2QmZ36GXwP4JjRvf+8/A/9wJUveC88D8pMgyFsMPwP7wIYsHraPI/AAAAAAAA+P8AAAAAAAD4/wAAAAAAAPj/AAAAAAAA+P/btm3btm3rPwAAAAAAAPj/gTHYyiXK8j8AAAAAAAD4/4Ex2MolyvI/AAAAAAAA+P8AAAAAAAD4/wAAAAAAAPj/AAAAAAAA+P8AAAAAAAD4/wAAAAAAAPj/AAAAAAAA+P8AAAAAAAD4/wAAAAAAAPj/AAAAAAAA+P8AAAAAAAD4/wAAAAAAAPj/AAAAAAAA+P8AAAAAAAD4/w==\",\"dtype\":\"float64\",\"shape\":[56]},\"x\":[0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0,16.0,17.0,18.0,19.0,20.0,21.0,22.0,23.0,24.0,25.0,26.0,27.0,28.0,29.0,30.0,31.0,32.0,33.0,34.0,35.0,36.0,37.0,38.0,39.0,40.0,41.0,42.0,43.0,44.0,45.0,46.0,47.0,48.0,51.0,54.0,56.0,57.0,60.0,61.0,71.0]},\"selected\":{\"id\":\"1149\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1148\",\"type\":\"UnionRenderers\"}},\"id\":\"1112\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"callback\":null,\"data\":{\"lower\":{\"__ndarray__\":\"mEkxIb7D7j8AymEwnAfuP5PfTFaas+0/5LMcZ6nw7D+W4yIvKeLrP1lck95+Z+o/4ZmDoMOu6z9hvFLlF0brP58Nl1RCH+s/3ENnFQ2Z6j8QKf2DJ/3rP3WsGTbxGus/07yg+Jtu6T98CwUJ0oXoP25s3DmFJeg/LPvIaV746D/uPXSo5ILpP4WtH4iyaOw/+joUEmXv6T+/5mBRRODsP9MoqOs/JOk/+v4H+9QR5z8+Dgp/Wu3hP2g7cBgLQ+w/RJq8Xa886D/fT8rxjVXnP2jVR0G9p+g/DuU1lNdQ7j/43nvvvffuPwAAAAAAAPj/nud5nud57j9WrX1xudnnPwAAAAAAAPj/AAAAAAAA+P/btm3btm3rPwAAAAAAAPj/AAAAAAAA+P/9OZ/UaNfUP53YiZ3Yie0/6ofYJ7Wxzj8AAAAAAAD4/1VVVVVVVeU/AAAAAAAA+P8AAAAAAAD4/wAAAAAAAPj/AAAAAAAA+P8AAAAAAAD4/wAAAAAAAPj/AAAAAAAA+P8AAAAAAAD4/wAAAAAAAPj/AAAAAAAA+P8AAAAAAAD4/wAAAAAAAPj/AAAAAAAA+P8AAAAAAAD4/w==\",\"dtype\":\"float64\",\"shape\":[56]},\"upper\":{\"__ndarray__\":\"JvgDRuH67j9g39sLlGnuP9exI86TP+4/fMMuISbG7T9IhyHFlyftP4ucjJEIN+w/w1A8n/uO7T/vqdBow37tP+/t3vSipO0/MLYbqZOW7T+w24AHSanuP7824u0TeO4/YQF5YR+h7T/evD0N4ArtPwyuhH8i7O0/DHdazRMr7j9C+qraDq/uP37HAqDQDPA/WhpBQ/Bl7z/1j8qeslDwP2dlO01Ov+8/ZDwo3Dm67j/C8fWApRLuPwQBTV/MlvA/+uc+qz7n7z9MFFdDdZHwP74ajRikRPA/DuU1lNdQ7j/43nvvvffuPwAAAAAAAPj/nud5nud57j8pMgyFsMPwPwAAAAAAAPj/AAAAAAAA+P/btm3btm3rPwAAAAAAAPj/AAAAAAAA+P+BMdjKJcryP53YiZ3Yie0/V0RasB5/8T8AAAAAAAD4/1VVVVVVVeU/AAAAAAAA+P8AAAAAAAD4/wAAAAAAAPj/AAAAAAAA+P8AAAAAAAD4/wAAAAAAAPj/AAAAAAAA+P8AAAAAAAD4/wAAAAAAAPj/AAAAAAAA+P8AAAAAAAD4/wAAAAAAAPj/AAAAAAAA+P8AAAAAAAD4/w==\",\"dtype\":\"float64\",\"shape\":[56]},\"x\":[0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0,16.0,17.0,18.0,19.0,20.0,21.0,22.0,23.0,24.0,25.0,26.0,27.0,28.0,29.0,30.0,31.0,32.0,33.0,34.0,35.0,36.0,37.0,38.0,39.0,40.0,41.0,42.0,43.0,44.0,45.0,46.0,47.0,48.0,51.0,54.0,56.0,57.0,60.0,61.0,71.0]},\"selected\":{\"id\":\"1250\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1249\",\"type\":\"UnionRenderers\"}},\"id\":\"1200\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"callback\":null,\"data\":{\"x\":[0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0,16.0,17.0,18.0,19.0,20.0,21.0,22.0,23.0,24.0,25.0,26.0,27.0,28.0,29.0,30.0,31.0,32.0,33.0,34.0,35.0,36.0,37.0,38.0,39.0,40.0,41.0,42.0,43.0,44.0,45.0,46.0,47.0,48.0,51.0,54.0,56.0,57.0,60.0,61.0,71.0],\"y\":{\"__ndarray__\":\"6ZbPPtnw7D9KPrD1Yd3oPx/RjvlmN+c/8GezjmoR5T8VvJyCl1PkPxkg8dSQAeI/jWuRoKZC5D+eEuQpQZ7iPyPBQutfxOM/2FBeQ3kN5T9ay9ABuz3mP+iphZWeWug/3VWKCbqr5D9AOpYyCXblP2ApUOtXCuQ/L6l8GPfr4j9JkiRJkiTpP2IndmInduo/nvGMZzzj6T8/+OCDDz7oP1lHm/cpLuk/////////5D/UQR3UQR3kP73pTW960+s/exSuR+F65D93Yid2YifmP1uwBVuwBes/q6qqqqqq6j/UCMs9jbDsPx3HcRzHcew/lpaWlpaW5j9u27Zt27btP5uZmZmZmek/VFVVVVVV5T8AAAAAAADoPwAAAAAAAPA/HcdxHMdx7D/btm3btm3rPxdddNFFF+0/27Zt27Zt6z8AAAAAAADwP1VVVVVVVdU/AAAAAAAA8D8AAAAAAADwPwAAAAAAAAAAAAAAAAAA8D8AAAAAAADwPwAAAAAAAPA/AAAAAAAA8D8AAAAAAADwPwAAAAAAAAAAAAAAAAAAAAAAAAAAAADwPwAAAAAAAPA/AAAAAAAA8D8AAAAAAADwPw==\",\"dtype\":\"float64\",\"shape\":[56]}},\"selected\":{\"id\":\"1045\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1044\",\"type\":\"UnionRenderers\"}},\"id\":\"1027\",\"type\":\"ColumnDataSource\"},{\"attributes\":{},\"id\":\"1150\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"callback\":null,\"data\":{\"x\":[0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0,16.0,17.0,18.0,19.0,20.0,21.0,22.0,23.0,24.0,25.0,26.0,27.0,28.0,29.0,30.0,31.0,32.0,33.0,34.0,35.0,36.0,37.0,38.0,39.0,40.0,41.0,42.0,43.0,44.0,45.0,46.0,47.0,48.0,51.0,54.0,56.0,57.0,60.0,61.0,71.0],\"y\":{\"__ndarray__\":\"XzRVkBTT7T8WptpK/53qP26YRROfUOk/8lNk2Ztg5z8XgsEL7MbmP6+0VlorreU/aoTlnkZY5j9uXd4BR4rmP/FXviSL8ec/41YoboXi5j+AoZqOuUToP8+xRiIgPuo/n+d5nud55j/IpHiBTIrnP9FeQnsJ7eU/YuL9yGm+5j8ZrNAZrNDpPzuxEzuxE+s/WaAFWqAF6j+ZmZmZmZnpP5/ikiFYR+s/AAAAAAAA6D91gynyWTfoP1VVVVVVVe0/2Ymd2Imd6D+bmZmZmZnpP2ijvrNR3+k/z7rBFPms6z+7u7u7u7vrP0dY7mmE5e4/Ka+hvIby6j/UCMs9jbDsPwAAAAAAAPA/VFVVVVVV5T/btm3btm3rPwAAAAAAAPA/AAAAAAAA8D/btm3btm3rPxdddNFFF+0/AAAAAAAA6D8AAAAAAADwP1VVVVVVVeU/AAAAAAAA8D8AAAAAAADwPwAAAAAAAPA/AAAAAAAA8D8AAAAAAADwPwAAAAAAAPA/AAAAAAAA8D8AAAAAAADwPwAAAAAAAPA/AAAAAAAAAAAAAAAAAADwPwAAAAAAAPA/AAAAAAAA8D8AAAAAAADwPw==\",\"dtype\":\"float64\",\"shape\":[56]}},\"selected\":{\"id\":\"1151\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1150\",\"type\":\"UnionRenderers\"}},\"id\":\"1115\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"plot\":null,\"text\":\"\"},\"id\":\"1039\",\"type\":\"Title\"},{\"attributes\":{\"plot\":{\"id\":\"1003\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"ticker\":{\"id\":\"1013\",\"type\":\"BasicTicker\"}},\"id\":\"1016\",\"type\":\"Grid\"},{\"attributes\":{\"data_source\":{\"id\":\"1120\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1121\",\"type\":\"Scatter\"},\"hover_glyph\":{\"id\":\"1123\",\"type\":\"Scatter\"},\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1122\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1125\",\"type\":\"CDSView\"}},\"id\":\"1124\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_color\":{\"value\":\"#1f77b4\"},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"diamond\"},\"size\":{\"units\":\"screen\",\"value\":12},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1033\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"diamond\"},\"size\":{\"units\":\"screen\",\"value\":12},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1034\",\"type\":\"Scatter\"},{\"attributes\":{\"line_color\":\"#9467bd\",\"line_width\":2,\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1157\",\"type\":\"Line\"},{\"attributes\":{},\"id\":\"1197\",\"type\":\"UnionRenderers\"},{\"attributes\":{},\"id\":\"1198\",\"type\":\"Selection\"},{\"attributes\":{\"fill_color\":{\"value\":\"Gray\"},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"units\":\"screen\",\"value\":12},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1088\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_color\":{\"value\":\"#d62728\"},\"line_color\":{\"value\":\"#d62728\"},\"marker\":{\"value\":\"square\"},\"size\":{\"units\":\"screen\",\"value\":12},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1121\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_color\":{\"value\":\"Gray\"},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square\"},\"size\":{\"units\":\"screen\",\"value\":12},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1123\",\"type\":\"Scatter\"},{\"attributes\":{},\"id\":\"1109\",\"type\":\"UnionRenderers\"},{\"attributes\":{},\"id\":\"1147\",\"type\":\"Selection\"},{\"attributes\":{\"base\":{\"field\":\"x\",\"units\":\"data\"},\"fill_color\":{\"value\":\"#aec7e8\"},\"level\":\"underlay\",\"line_color\":{\"value\":\"#1f77b4\"},\"lower\":{\"field\":\"lower\",\"units\":\"data\"},\"plot\":{\"id\":\"1003\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"source\":{\"id\":\"1048\",\"type\":\"ColumnDataSource\"},\"upper\":{\"field\":\"upper\",\"units\":\"data\"}},\"id\":\"1049\",\"type\":\"Band\"},{\"attributes\":{\"label\":{\"value\":\"CNN1\"},\"renderers\":[{\"id\":\"1060\",\"type\":\"GlyphRenderer\"}]},\"id\":\"1076\",\"type\":\"LegendItem\"},{\"attributes\":{},\"id\":\"1151\",\"type\":\"Selection\"},{\"attributes\":{\"fill_color\":{\"value\":\"#2ca02c\"},\"line_color\":{\"value\":\"#2ca02c\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"units\":\"screen\",\"value\":12},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1086\",\"type\":\"Scatter\"},{\"attributes\":{\"callback\":null,\"data\":{\"x\":[0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0,16.0,17.0,18.0,19.0,20.0,21.0,22.0,23.0,24.0,25.0,26.0,27.0,28.0,29.0,30.0,31.0,32.0,33.0,34.0,35.0,36.0,37.0,38.0,39.0,40.0,41.0,42.0,43.0,44.0,45.0,46.0,47.0,48.0,51.0,54.0,56.0,57.0,60.0,61.0,71.0],\"y\":{\"__ndarray__\":\"8TSSWFx67j8Vhc8XudXtPw+fFawaO+0/fcPaN6x96z8xc7lZrwrrPz1pTI6uG+k/nKCntdEJ6j+dfltp1rjoP5GFLGQhC+k/GJdJToRx6T+YRoEIjl3qP9qKoOGk7us/3RF3xB1x5z8DGnfrvALqP27btm3btuU/2erZIXBj6T8+jbDc0wjrPxQ7sRM7ses/dtlll1126T+CRCtsDiTqP5/ikiFYR+s/BJWzW/jV6D9UVVVVVVXlP4OXU/ByCu4/KHZiJ3Zi5z/uaYTlnkboP73pTW960+s/fNYNpshn7T+7u7u7u7vrP97d3d3d3e0/L7rooosu6j/UCMs9jbDsP5uZmZmZmek/AAAAAAAA8D8AAAAAAADwPwAAAAAAAPA/AAAAAAAA8D/btm3btm3rPwAAAAAAAPA/AAAAAAAA6D8AAAAAAADwPwAAAAAAAOg/AAAAAAAA8D8AAAAAAADwPwAAAAAAAAAAAAAAAAAA8D8AAAAAAADwPwAAAAAAAPA/AAAAAAAA8D8AAAAAAADwPwAAAAAAAPA/AAAAAAAAAAAAAAAAAADwPwAAAAAAAPA/AAAAAAAA8D8AAAAAAADwPw==\",\"dtype\":\"float64\",\"shape\":[56]}},\"selected\":{\"id\":\"1147\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1146\",\"type\":\"UnionRenderers\"}},\"id\":\"1085\",\"type\":\"ColumnDataSource\"},{\"attributes\":{},\"id\":\"1194\",\"type\":\"Selection\"},{\"attributes\":{\"data_source\":{\"id\":\"1080\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1081\",\"type\":\"Line\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1082\",\"type\":\"Line\"},\"selection_glyph\":null,\"view\":{\"id\":\"1084\",\"type\":\"CDSView\"}},\"id\":\"1083\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"label\":{\"value\":\"Lex.\"},\"renderers\":[{\"id\":\"1036\",\"type\":\"GlyphRenderer\"}]},\"id\":\"1047\",\"type\":\"LegendItem\"},{\"attributes\":{\"fill_color\":{\"value\":\"#ff7f0e\"},\"line_color\":{\"value\":\"#ff7f0e\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"units\":\"screen\",\"value\":12},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1057\",\"type\":\"Scatter\"},{\"attributes\":{\"source\":{\"id\":\"1032\",\"type\":\"ColumnDataSource\"}},\"id\":\"1037\",\"type\":\"CDSView\"},{\"attributes\":{},\"id\":\"1146\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"callback\":null,\"data\":{\"x\":[0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0,16.0,17.0,18.0,19.0,20.0,21.0,22.0,23.0,24.0,25.0,26.0,27.0,28.0,29.0,30.0,31.0,32.0,33.0,34.0,35.0,36.0,37.0,38.0,39.0,40.0,41.0,42.0,43.0,44.0,45.0,46.0,47.0,48.0,51.0,54.0,56.0,57.0,60.0,61.0,71.0],\"y\":{\"__ndarray__\":\"rXIDavyb7j/jN6+R9H3tP95w4tAqjew/18doKf/i6j/lCDxVf5vpP7d8y7d8y+c/ualonlAL6D/XsLJOZmvoPwps2k+WwOY/e492sfdo5z8c6LSBThvoP6zBcwSKtuo/hmEYhmEY5j/vaYTlnkboP+JCzUkgLuQ/45IhWEeb5z8yncV0FtPpPxqt0Rqt0eo/mpmZmZmZ6T/Mli1btmzpP////////+g/AAAAAAAA6T9UVVVVVVXlP4OXU/ByCu4/C9ejcD0K5z98GmG5pxHmPy+66KKLLuo/G8prKK+h7D/UCMs9jbDsP27btm3btu0/zczMzMzM7D+8u7u7u7vrPx3HcRzHcew/AAAAAAAA8D8AAAAAAADoPwAAAAAAAPA/AAAAAAAA8D8AAAAAAADoPwAAAAAAAPA/kyRJkiRJ4j8AAAAAAADwPwAAAAAAAOA/AAAAAAAA8D8AAAAAAADwPwAAAAAAAAAAAAAAAAAA8D8AAAAAAADwPwAAAAAAAPA/AAAAAAAA8D8AAAAAAADwPwAAAAAAAAAAAAAAAAAAAAAAAAAAAADwPwAAAAAAAPA/AAAAAAAA8D8AAAAAAADwPw==\",\"dtype\":\"float64\",\"shape\":[56]}},\"selected\":{\"id\":\"1075\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1074\",\"type\":\"UnionRenderers\"}},\"id\":\"1051\",\"type\":\"ColumnDataSource\"},{\"attributes\":{},\"id\":\"1249\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"callback\":null,\"data\":{\"x\":[0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0,16.0,17.0,18.0,19.0,20.0,21.0,22.0,23.0,24.0,25.0,26.0,27.0,28.0,29.0,30.0,31.0,32.0,33.0,34.0,35.0,36.0,37.0,38.0,39.0,40.0,41.0,42.0,43.0,44.0,45.0,46.0,47.0,48.0,51.0,54.0,56.0,57.0,60.0,61.0,71.0],\"y\":{\"__ndarray__\":\"6ZbPPtnw7D9KPrD1Yd3oPx/RjvlmN+c/8GezjmoR5T8VvJyCl1PkPxkg8dSQAeI/jWuRoKZC5D+eEuQpQZ7iPyPBQutfxOM/2FBeQ3kN5T9ay9ABuz3mP+iphZWeWug/3VWKCbqr5D9AOpYyCXblP2ApUOtXCuQ/L6l8GPfr4j9JkiRJkiTpP2IndmInduo/nvGMZzzj6T8/+OCDDz7oP1lHm/cpLuk/////////5D/UQR3UQR3kP73pTW960+s/exSuR+F65D93Yid2YifmP1uwBVuwBes/q6qqqqqq6j/UCMs9jbDsPx3HcRzHcew/lpaWlpaW5j9u27Zt27btP5uZmZmZmek/VFVVVVVV5T8AAAAAAADoPwAAAAAAAPA/HcdxHMdx7D/btm3btm3rPxdddNFFF+0/27Zt27Zt6z8AAAAAAADwP1VVVVVVVdU/AAAAAAAA8D8AAAAAAADwPwAAAAAAAAAAAAAAAAAA8D8AAAAAAADwPwAAAAAAAPA/AAAAAAAA8D8AAAAAAADwPwAAAAAAAAAAAAAAAAAAAAAAAAAAAADwPwAAAAAAAPA/AAAAAAAA8D8AAAAAAADwPw==\",\"dtype\":\"float64\",\"shape\":[56]}},\"selected\":{\"id\":\"1071\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1070\",\"type\":\"UnionRenderers\"}},\"id\":\"1032\",\"type\":\"ColumnDataSource\"},{\"attributes\":{},\"id\":\"1008\",\"type\":\"LinearScale\"},{\"attributes\":{},\"id\":\"1107\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"line_color\":\"#d62728\",\"line_width\":2,\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1116\",\"type\":\"Line\"},{\"attributes\":{\"dimension\":1,\"plot\":{\"id\":\"1003\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"ticker\":{\"id\":\"1018\",\"type\":\"BasicTicker\"}},\"id\":\"1021\",\"type\":\"Grid\"},{\"attributes\":{},\"id\":\"1045\",\"type\":\"Selection\"},{\"attributes\":{\"axis_label\":\"F1 Score\",\"axis_label_text_font_size\":{\"value\":\"14pt\"},\"bounds\":[0,1],\"formatter\":{\"id\":\"1042\",\"type\":\"BasicTickFormatter\"},\"major_label_text_font_size\":{\"value\":\"13pt\"},\"plot\":{\"id\":\"1003\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"ticker\":{\"id\":\"1018\",\"type\":\"BasicTicker\"}},\"id\":\"1017\",\"type\":\"LinearAxis\"},{\"attributes\":{},\"id\":\"1149\",\"type\":\"Selection\"},{\"attributes\":{\"base\":{\"field\":\"x\",\"units\":\"data\"},\"fill_color\":{\"value\":\"#98df8a\"},\"level\":\"underlay\",\"line_color\":{\"value\":\"#2ca02c\"},\"lower\":{\"field\":\"lower\",\"units\":\"data\"},\"plot\":{\"id\":\"1003\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"source\":{\"id\":\"1112\",\"type\":\"ColumnDataSource\"},\"upper\":{\"field\":\"upper\",\"units\":\"data\"}},\"id\":\"1113\",\"type\":\"Band\"},{\"attributes\":{},\"id\":\"1247\",\"type\":\"UnionRenderers\"},{\"attributes\":{},\"id\":\"1110\",\"type\":\"Selection\"},{\"attributes\":{\"label\":{\"value\":\"Full\"},\"renderers\":[{\"id\":\"1165\",\"type\":\"GlyphRenderer\"}]},\"id\":\"1199\",\"type\":\"LegendItem\"},{\"attributes\":{\"line_alpha\":0.1,\"line_color\":\"#1f77b4\",\"line_width\":2,\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1117\",\"type\":\"Line\"},{\"attributes\":{},\"id\":\"1042\",\"type\":\"BasicTickFormatter\"},{\"attributes\":{},\"id\":\"1106\",\"type\":\"Selection\"},{\"attributes\":{},\"id\":\"1040\",\"type\":\"BasicTickFormatter\"},{\"attributes\":{},\"id\":\"1072\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"source\":{\"id\":\"1115\",\"type\":\"ColumnDataSource\"}},\"id\":\"1119\",\"type\":\"CDSView\"},{\"attributes\":{},\"id\":\"1105\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"source\":{\"id\":\"1080\",\"type\":\"ColumnDataSource\"}},\"id\":\"1084\",\"type\":\"CDSView\"},{\"attributes\":{\"base\":{\"field\":\"x\",\"units\":\"data\"},\"fill_color\":{\"value\":\"#ff9896\"},\"level\":\"underlay\",\"line_color\":{\"value\":\"#d62728\"},\"lower\":{\"field\":\"lower\",\"units\":\"data\"},\"plot\":{\"id\":\"1003\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"source\":{\"id\":\"1153\",\"type\":\"ColumnDataSource\"},\"upper\":{\"field\":\"upper\",\"units\":\"data\"}},\"id\":\"1154\",\"type\":\"Band\"},{\"attributes\":{\"data_source\":{\"id\":\"1027\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1028\",\"type\":\"Line\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1029\",\"type\":\"Line\"},\"selection_glyph\":null,\"view\":{\"id\":\"1031\",\"type\":\"CDSView\"}},\"id\":\"1030\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"line_color\":\"#ff7f0e\",\"line_width\":2,\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1052\",\"type\":\"Line\"},{\"attributes\":{\"source\":{\"id\":\"1156\",\"type\":\"ColumnDataSource\"}},\"id\":\"1160\",\"type\":\"CDSView\"},{\"attributes\":{\"data_source\":{\"id\":\"1156\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1157\",\"type\":\"Line\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1158\",\"type\":\"Line\"},\"selection_glyph\":null,\"view\":{\"id\":\"1160\",\"type\":\"CDSView\"}},\"id\":\"1159\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"line_alpha\":0.1,\"line_color\":\"#1f77b4\",\"line_width\":2,\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1053\",\"type\":\"Line\"},{\"attributes\":{\"callback\":null,\"data\":{\"x\":[0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0,16.0,17.0,18.0,19.0,20.0,21.0,22.0,23.0,24.0,25.0,26.0,27.0,28.0,29.0,30.0,31.0,32.0,33.0,34.0,35.0,36.0,37.0,38.0,39.0,40.0,41.0,42.0,43.0,44.0,45.0,46.0,47.0,48.0,51.0,54.0,56.0,57.0,60.0,61.0,71.0],\"y\":{\"__ndarray__\":\"rXIDavyb7j/jN6+R9H3tP95w4tAqjew/18doKf/i6j/lCDxVf5vpP7d8y7d8y+c/ualonlAL6D/XsLJOZmvoPwps2k+WwOY/e492sfdo5z8c6LSBThvoP6zBcwSKtuo/hmEYhmEY5j/vaYTlnkboP+JCzUkgLuQ/45IhWEeb5z8yncV0FtPpPxqt0Rqt0eo/mpmZmZmZ6T/Mli1btmzpP////////+g/AAAAAAAA6T9UVVVVVVXlP4OXU/ByCu4/C9ejcD0K5z98GmG5pxHmPy+66KKLLuo/G8prKK+h7D/UCMs9jbDsP27btm3btu0/zczMzMzM7D+8u7u7u7vrPx3HcRzHcew/AAAAAAAA8D8AAAAAAADoPwAAAAAAAPA/AAAAAAAA8D8AAAAAAADoPwAAAAAAAPA/kyRJkiRJ4j8AAAAAAADwPwAAAAAAAOA/AAAAAAAA8D8AAAAAAADwPwAAAAAAAAAAAAAAAAAA8D8AAAAAAADwPwAAAAAAAPA/AAAAAAAA8D8AAAAAAADwPwAAAAAAAAAAAAAAAAAAAAAAAAAAAADwPwAAAAAAAPA/AAAAAAAA8D8AAAAAAADwPw==\",\"dtype\":\"float64\",\"shape\":[56]}},\"selected\":{\"id\":\"1106\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1105\",\"type\":\"UnionRenderers\"}},\"id\":\"1056\",\"type\":\"ColumnDataSource\"},{\"attributes\":{},\"id\":\"1018\",\"type\":\"BasicTicker\"},{\"attributes\":{},\"id\":\"1071\",\"type\":\"Selection\"},{\"attributes\":{\"data_source\":{\"id\":\"1085\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1086\",\"type\":\"Scatter\"},\"hover_glyph\":{\"id\":\"1088\",\"type\":\"Scatter\"},\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1087\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1090\",\"type\":\"CDSView\"}},\"id\":\"1089\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"base\":{\"field\":\"x\",\"units\":\"data\"},\"fill_color\":{\"value\":\"#ffbb78\"},\"level\":\"underlay\",\"line_color\":{\"value\":\"#ff7f0e\"},\"lower\":{\"field\":\"lower\",\"units\":\"data\"},\"plot\":{\"id\":\"1003\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"source\":{\"id\":\"1077\",\"type\":\"ColumnDataSource\"},\"upper\":{\"field\":\"upper\",\"units\":\"data\"}},\"id\":\"1078\",\"type\":\"Band\"},{\"attributes\":{\"line_alpha\":0.1,\"line_color\":\"#1f77b4\",\"line_width\":2,\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1082\",\"type\":\"Line\"},{\"attributes\":{\"data_source\":{\"id\":\"1032\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1033\",\"type\":\"Scatter\"},\"hover_glyph\":{\"id\":\"1035\",\"type\":\"Scatter\"},\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1034\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1037\",\"type\":\"CDSView\"}},\"id\":\"1036\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"callback\":null,\"data\":{\"x\":[0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0,16.0,17.0,18.0,19.0,20.0,21.0,22.0,23.0,24.0,25.0,26.0,27.0,28.0,29.0,30.0,31.0,32.0,33.0,34.0,35.0,36.0,37.0,38.0,39.0,40.0,41.0,42.0,43.0,44.0,45.0,46.0,47.0,48.0,51.0,54.0,56.0,57.0,60.0,61.0,71.0],\"y\":{\"__ndarray__\":\"36Cas0/f7j+w1B4emDjuP7VIOBKX+e0/sLslxGdb7T9vNSJ64ITsP3L8D7hDT+s/UvXfn9+e7D8osxGnbWLsP8f9uqTyYew/Bn1BX9AX7D9gAr9FOFPtP5rx/ZGCyew/Gt8Mrd2H6z8tZCELWcjqPz2NsNzTCOs/HLmRG7mR6z8YnI/B+RjsP0GeEuQpQe4/qqqqqqqq7D9UA3vH1MDuPx3HcRzHcew/rx2Yawfm6j8AAAAAAADoP7gehetRuO4/H8F9BPcR7D88PDw8PDzsP3IFMbmCmOw/DuU1lNdQ7j/43nvvvffuPwAAAAAAAPA/nud5nud57j/UCMs9jbDsPwAAAAAAAPA/AAAAAAAA8D/btm3btm3rPwAAAAAAAPA/AAAAAAAA8D8AAAAAAADoP53YiZ3Yie0/VFVVVVVV5T8AAAAAAADwP1VVVVVVVeU/AAAAAAAA8D8AAAAAAADwPwAAAAAAAPA/AAAAAAAA8D8AAAAAAADwPwAAAAAAAPA/AAAAAAAA8D8AAAAAAADwPwAAAAAAAPA/AAAAAAAA8D8AAAAAAADwPwAAAAAAAPA/AAAAAAAA8D8AAAAAAADwPw==\",\"dtype\":\"float64\",\"shape\":[56]}},\"selected\":{\"id\":\"1248\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1247\",\"type\":\"UnionRenderers\"}},\"id\":\"1161\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"label\":{\"value\":\"CNN2\"},\"renderers\":[{\"id\":\"1089\",\"type\":\"GlyphRenderer\"}]},\"id\":\"1111\",\"type\":\"LegendItem\"},{\"attributes\":{},\"id\":\"1073\",\"type\":\"Selection\"},{\"attributes\":{\"label\":{\"value\":\"Ortho.\"},\"renderers\":[{\"id\":\"1124\",\"type\":\"GlyphRenderer\"}]},\"id\":\"1152\",\"type\":\"LegendItem\"},{\"attributes\":{\"callback\":null,\"data\":{\"x\":[0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0,16.0,17.0,18.0,19.0,20.0,21.0,22.0,23.0,24.0,25.0,26.0,27.0,28.0,29.0,30.0,31.0,32.0,33.0,34.0,35.0,36.0,37.0,38.0,39.0,40.0,41.0,42.0,43.0,44.0,45.0,46.0,47.0,48.0,51.0,54.0,56.0,57.0,60.0,61.0,71.0],\"y\":{\"__ndarray__\":\"8TSSWFx67j8Vhc8XudXtPw+fFawaO+0/fcPaN6x96z8xc7lZrwrrPz1pTI6uG+k/nKCntdEJ6j+dfltp1rjoP5GFLGQhC+k/GJdJToRx6T+YRoEIjl3qP9qKoOGk7us/3RF3xB1x5z8DGnfrvALqP27btm3btuU/2erZIXBj6T8+jbDc0wjrPxQ7sRM7ses/dtlll1126T+CRCtsDiTqP5/ikiFYR+s/BJWzW/jV6D9UVVVVVVXlP4OXU/ByCu4/KHZiJ3Zi5z/uaYTlnkboP73pTW960+s/fNYNpshn7T+7u7u7u7vrP97d3d3d3e0/L7rooosu6j/UCMs9jbDsP5uZmZmZmek/AAAAAAAA8D8AAAAAAADwPwAAAAAAAPA/AAAAAAAA8D/btm3btm3rPwAAAAAAAPA/AAAAAAAA6D8AAAAAAADwPwAAAAAAAOg/AAAAAAAA8D8AAAAAAADwPwAAAAAAAAAAAAAAAAAA8D8AAAAAAADwPwAAAAAAAPA/AAAAAAAA8D8AAAAAAADwPwAAAAAAAPA/AAAAAAAAAAAAAAAAAADwPwAAAAAAAPA/AAAAAAAA8D8AAAAAAADwPw==\",\"dtype\":\"float64\",\"shape\":[56]}},\"selected\":{\"id\":\"1110\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1109\",\"type\":\"UnionRenderers\"}},\"id\":\"1080\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"callback\":null,\"data\":{\"lower\":{\"__ndarray__\":\"x4CW/6Su7T9iEJkEiU/qPxOtyhQn2ug/B+T2T8ut5j9l2lmpVtTlP4dwvepzceQ/zRH0BzTh5D8U78un7t/kP1JlnrxEMOY/0IjuFhm65D8TuvJWvizmPyUQ8ziXF+g/YKTwncmA4z8HsYSZSsXkP4GZYiErGOI/zXf/TSQ74z9R8fERR67mP1sk2hMkLug/cnyMULyQ5j+NwJJ6KZHlP0ChvPYvp+c/Uee7re1+4z+Gk32vjh7iP0mhTQTjG+o/IMNsyrrE4z+ZnvPmaQvkP774R1gKzOQ/42ZcHzRO5z8K8qqIpqvmP0dY7mmE5e4/Ka+hvIby6j9WrX1xudnnPwAAAAAAAPj/6ofYJ7Wxzj/btm3btm3rPwAAAAAAAPj/AAAAAAAA+P/btm3btm3rPxdddNFFF+0//Tmf1GjX1D8AAAAAAAD4/1VVVVVVVeU/AAAAAAAA+P8AAAAAAAD4/wAAAAAAAPj/AAAAAAAA+P8AAAAAAAD4/wAAAAAAAPj/AAAAAAAA+P8AAAAAAAD4/wAAAAAAAPj/AAAAAAAA+P8AAAAAAAD4/wAAAAAAAPj/AAAAAAAA+P8AAAAAAAD4/w==\",\"dtype\":\"float64\",\"shape\":[56]},\"upper\":{\"__ndarray__\":\"9+cTIYT37T/KOxyRdezqP8mDwBEXx+k/3cPRYmwT6D/JKSlugbnnP9f478ni6OY/B/fWNVnP5z/Iy/BbnzToP5BK3ozRsuk/9iRixfEK6T/tiELGtFzqP3lTmgupZOw/3ioDnwVz6T+JmGxpTk/qPyEkItXnwek/90z8Q69B6j/hZq8hEfPsPxs+TWI++e0/QMR+Y4R67T+lcqC4CaLtP/4jaUyA5+4/rxhEUhKB7D9kc9U0JVDuP7CELtNjR/A/klDO5lh27T+dlD9MySfvPxJONQ+Z8u4/XocTBd8F8D+2QmZ36GXwP0dY7mmE5e4/Ka+hvIby6j8pMgyFsMPwPwAAAAAAAPj/V0RasB5/8T/btm3btm3rPwAAAAAAAPj/AAAAAAAA+P/btm3btm3rPxdddNFFF+0/gTHYyiXK8j8AAAAAAAD4/1VVVVVVVeU/AAAAAAAA+P8AAAAAAAD4/wAAAAAAAPj/AAAAAAAA+P8AAAAAAAD4/wAAAAAAAPj/AAAAAAAA+P8AAAAAAAD4/wAAAAAAAPj/AAAAAAAA+P8AAAAAAAD4/wAAAAAAAPj/AAAAAAAA+P8AAAAAAAD4/w==\",\"dtype\":\"float64\",\"shape\":[56]},\"x\":[0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0,16.0,17.0,18.0,19.0,20.0,21.0,22.0,23.0,24.0,25.0,26.0,27.0,28.0,29.0,30.0,31.0,32.0,33.0,34.0,35.0,36.0,37.0,38.0,39.0,40.0,41.0,42.0,43.0,44.0,45.0,46.0,47.0,48.0,51.0,54.0,56.0,57.0,60.0,61.0,71.0]},\"selected\":{\"id\":\"1196\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1195\",\"type\":\"UnionRenderers\"}},\"id\":\"1153\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"callback\":null,\"data\":{\"x\":[0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0,16.0,17.0,18.0,19.0,20.0,21.0,22.0,23.0,24.0,25.0,26.0,27.0,28.0,29.0,30.0,31.0,32.0,33.0,34.0,35.0,36.0,37.0,38.0,39.0,40.0,41.0,42.0,43.0,44.0,45.0,46.0,47.0,48.0,51.0,54.0,56.0,57.0,60.0,61.0,71.0],\"y\":{\"__ndarray__\":\"36Cas0/f7j+w1B4emDjuP7VIOBKX+e0/sLslxGdb7T9vNSJ64ITsP3L8D7hDT+s/UvXfn9+e7D8osxGnbWLsP8f9uqTyYew/Bn1BX9AX7D9gAr9FOFPtP5rx/ZGCyew/Gt8Mrd2H6z8tZCELWcjqPz2NsNzTCOs/HLmRG7mR6z8YnI/B+RjsP0GeEuQpQe4/qqqqqqqq7D9UA3vH1MDuPx3HcRzHcew/rx2Yawfm6j8AAAAAAADoP7gehetRuO4/H8F9BPcR7D88PDw8PDzsP3IFMbmCmOw/DuU1lNdQ7j/43nvvvffuPwAAAAAAAPA/nud5nud57j/UCMs9jbDsPwAAAAAAAPA/AAAAAAAA8D/btm3btm3rPwAAAAAAAPA/AAAAAAAA8D8AAAAAAADoP53YiZ3Yie0/VFVVVVVV5T8AAAAAAADwP1VVVVVVVeU/AAAAAAAA8D8AAAAAAADwPwAAAAAAAPA/AAAAAAAA8D8AAAAAAADwPwAAAAAAAPA/AAAAAAAA8D8AAAAAAADwPwAAAAAAAPA/AAAAAAAA8D8AAAAAAADwPwAAAAAAAPA/AAAAAAAA8D8AAAAAAADwPw==\",\"dtype\":\"float64\",\"shape\":[56]}},\"selected\":{\"id\":\"1198\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1197\",\"type\":\"UnionRenderers\"}},\"id\":\"1156\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"source\":{\"id\":\"1085\",\"type\":\"ColumnDataSource\"}},\"id\":\"1090\",\"type\":\"CDSView\"},{\"attributes\":{\"line_alpha\":0.1,\"line_color\":\"#1f77b4\",\"line_width\":2,\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1029\",\"type\":\"Line\"},{\"attributes\":{\"line_color\":\"#2ca02c\",\"line_width\":2,\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1081\",\"type\":\"Line\"},{\"attributes\":{\"fill_color\":{\"value\":\"#9467bd\"},\"line_color\":{\"value\":\"#9467bd\"},\"size\":{\"units\":\"screen\",\"value\":12},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1162\",\"type\":\"Scatter\"},{\"attributes\":{\"source\":{\"id\":\"1027\",\"type\":\"ColumnDataSource\"}},\"id\":\"1031\",\"type\":\"CDSView\"},{\"attributes\":{\"callback\":null,\"data\":{\"lower\":{\"__ndarray__\":\"tjm4bW197j+FcW2Mx0TtP60NvsMtNOw/5AUScbFS6j9uA2pBysnoP4//4qstqeY/MTAxsQut5j+dvbnCxujmP2AwVizI3uQ/nYN/6XlM5T9+CtOdBvzlP6FGEDajxeg/jm2OUB8S4z9SSUDjM6blP7K43MSnKeA/yx4G3NI65D/8WuKsn9TmP6kOAWJOyec/cIT1hgwP5j/ctRvZRUXlP1rg/80ocOQ//bF50VLW5D9Od0ufwgHdP8k5OT+2Hus/jl9UgPXa4T8IvrB7MPHdP8DB5oTYZeU/vWnbqlaX6D/UCMs9jbDsP27btm3btu0/zczMzMzM7D/gFCVKdTrmPx3HcRzHcew/AAAAAAAA+P/9OZ/UaNfUPwAAAAAAAPj/AAAAAAAA+P/9OZ/UaNfUPwAAAAAAAPj/MKt1FbEKrz8AAAAAAAD4/4AUrkfheoQ/AAAAAAAA+P8AAAAAAAD4/wAAAAAAAPj/AAAAAAAA+P8AAAAAAAD4/wAAAAAAAPj/AAAAAAAA+P8AAAAAAAD4/wAAAAAAAPj/AAAAAAAA+P8AAAAAAAD4/wAAAAAAAPj/AAAAAAAA+P8AAAAAAAD4/w==\",\"dtype\":\"float64\",\"shape\":[56]},\"upper\":{\"__ndarray__\":\"pKtOZou67j9B/vCWIbftPw/UBt4n5uw/yom/4Uxz6z9cDg5pNG3qP9/5s8PL7eg/QSOgi5Vp6T8RpKvaBe7pP7SnXnNkoug/WZtteXWF6T+6xZZlljrqP7c819Jwp+w/flWiu6Me6T+MisjnCefqPxLNvc6YMug/+wY91Lv76j9o36g8jdHsP4tLotML2u0/xK49rCYk7T+8dz/dJpTtP6QfADLXj+0/A06GLq0p7T8B7wRbySnsP576ttAXe/A/iE7zYIU57D/01ek0tyrtP56y6sA+9+4/PBX+0gNW8D/UCMs9jbDsP27btm3btu0/zczMzMzM7D9MMakWgZ7wPx3HcRzHcew/AAAAAAAA+P+BMdjKJcryPwAAAAAAAPj/AAAAAAAA+P+BMdjKJcryPwAAAAAAAPj/OnedCc9Q8T8AAAAAAAD4/65H4XoUru8/AAAAAAAA+P8AAAAAAAD4/wAAAAAAAPj/AAAAAAAA+P8AAAAAAAD4/wAAAAAAAPj/AAAAAAAA+P8AAAAAAAD4/wAAAAAAAPj/AAAAAAAA+P8AAAAAAAD4/wAAAAAAAPj/AAAAAAAA+P8AAAAAAAD4/w==\",\"dtype\":\"float64\",\"shape\":[56]},\"x\":[0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0,16.0,17.0,18.0,19.0,20.0,21.0,22.0,23.0,24.0,25.0,26.0,27.0,28.0,29.0,30.0,31.0,32.0,33.0,34.0,35.0,36.0,37.0,38.0,39.0,40.0,41.0,42.0,43.0,44.0,45.0,46.0,47.0,48.0,51.0,54.0,56.0,57.0,60.0,61.0,71.0]},\"selected\":{\"id\":\"1108\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1107\",\"type\":\"UnionRenderers\"}},\"id\":\"1077\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"background_fill_color\":{\"value\":null},\"border_line_color\":{\"value\":null},\"items\":[{\"id\":\"1047\",\"type\":\"LegendItem\"},{\"id\":\"1076\",\"type\":\"LegendItem\"},{\"id\":\"1111\",\"type\":\"LegendItem\"},{\"id\":\"1152\",\"type\":\"LegendItem\"},{\"id\":\"1199\",\"type\":\"LegendItem\"}],\"label_text_font_size\":{\"value\":\"14pt\"},\"orientation\":\"horizontal\",\"plot\":{\"id\":\"1003\",\"subtype\":\"Figure\",\"type\":\"Plot\"}},\"id\":\"1046\",\"type\":\"Legend\"},{\"attributes\":{\"callback\":null,\"data\":{\"lower\":{\"__ndarray__\":\"Bx4V8f/G7D/bhELxE4boP42/3Q+/tOY/nyhjk6RP5D9pr7MU+kzjPzZDrB5Xp+A/ZK820wmw4j/zqNpqt8PgP0QFZlN6t+E/9IKLJpLH4j+6EwL39vrjP3vK+N32++U/6q7z6EeF4T+Sa0TxCHTiP4UhEMOuD+A/ax4cw3P13T9kFAqiFgrmP0dFTVdgW+c/kHgS4th95j8p561FRBPkPx7V3CQetOQ/VB8Xasi23z/WcBLsqhfaP8ZyaVKBI+g/DriENa1W3T93Yid2YifmPyauyNhOfeY/xysB5cj+5T/UCMs9jbDsPx3HcRzHcew/lpaWlpaW5j9u27Zt27btP35D3mC3wtw/6ofYJ7Wxzj/9OZ/UaNfUPwAAAAAAAPj/HcdxHMdx7D/btm3btm3rPxdddNFFF+0/27Zt27Zt6z8AAAAAAAD4/1qwKhhvtci/AAAAAAAA+P8AAAAAAAD4/wAAAAAAAPj/AAAAAAAA+P8AAAAAAAD4/wAAAAAAAPj/AAAAAAAA+P8AAAAAAAD4/wAAAAAAAPj/AAAAAAAA+P8AAAAAAAD4/wAAAAAAAPj/AAAAAAAA+P8AAAAAAAD4/w==\",\"dtype\":\"float64\",\"shape\":[56]},\"upper\":{\"__ndarray__\":\"yw+KjLIa7T+59x36rzTpP7HiP+MOuuc/QacDijDT5T/ByIXwNFrlP/z8NYvKW+M/tifsbUPV5T9JfO3oynjkPwJ9H4NF0eU/vB4xYGBT5z/6gp8Mf4DoP1WJEk1Gueo/0PwgKizS5z/uCOhzCXjoPzsxkBMBBeg/KENrTzTd5j8uED/wDT/sP30Jn23ukO0/rGoH7Z9I7T9VCRTC2mjsP5S5Wco1qO0/VHD0ypsk6j89SzEyri7rP7RgMoxzg+8/78yZ9GtK6j93Yid2YifmP5CyQt0Rju8/jylUcIxW7z/UCMs9jbDsPx3HcRzHcew/lpaWlpaW5j9u27Zt27btP7wIYsHraPI/V0RasB5/8T+BMdjKJcryPwAAAAAAAPj/HcdxHMdx7D/btm3btm3rPxdddNFFF+0/27Zt27Zt6z8AAAAAAAD4/2wBYBuxgus/AAAAAAAA+P8AAAAAAAD4/wAAAAAAAPj/AAAAAAAA+P8AAAAAAAD4/wAAAAAAAPj/AAAAAAAA+P8AAAAAAAD4/wAAAAAAAPj/AAAAAAAA+P8AAAAAAAD4/wAAAAAAAPj/AAAAAAAA+P8AAAAAAAD4/w==\",\"dtype\":\"float64\",\"shape\":[56]},\"x\":[0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0,16.0,17.0,18.0,19.0,20.0,21.0,22.0,23.0,24.0,25.0,26.0,27.0,28.0,29.0,30.0,31.0,32.0,33.0,34.0,35.0,36.0,37.0,38.0,39.0,40.0,41.0,42.0,43.0,44.0,45.0,46.0,47.0,48.0,51.0,54.0,56.0,57.0,60.0,61.0,71.0]},\"selected\":{\"id\":\"1073\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1072\",\"type\":\"UnionRenderers\"}},\"id\":\"1048\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"callback\":null,\"end\":15.5,\"start\":-0.5},\"id\":\"1004\",\"type\":\"Range1d\"},{\"attributes\":{\"data_source\":{\"id\":\"1205\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1206\",\"type\":\"VBar\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1207\",\"type\":\"VBar\"},\"selection_glyph\":null,\"view\":{\"id\":\"1209\",\"type\":\"CDSView\"},\"y_range_name\":\"hist\"},\"id\":\"1208\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"top\":{\"field\":\"top\"},\"width\":{\"value\":0.9},\"x\":{\"field\":\"x\"}},\"id\":\"1207\",\"type\":\"VBar\"},{\"attributes\":{},\"id\":\"1250\",\"type\":\"Selection\"},{\"attributes\":{\"source\":{\"id\":\"1205\",\"type\":\"ColumnDataSource\"}},\"id\":\"1209\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_color\":{\"value\":\"Gray\"},\"line_color\":{\"value\":\"Gray\"},\"top\":{\"field\":\"top\"},\"width\":{\"value\":0.9},\"x\":{\"field\":\"x\"}},\"id\":\"1206\",\"type\":\"VBar\"},{\"attributes\":{\"callback\":null,\"end\":37456.66666666667,\"start\":1.0},\"id\":\"1203\",\"type\":\"Range1d\"},{\"attributes\":{\"axis_label_text_font_size\":{\"value\":\"14pt\"},\"bounds\":[1.0,11237.0],\"formatter\":{\"id\":\"1212\",\"type\":\"NumeralTickFormatter\"},\"major_label_text_font_size\":{\"value\":\"13pt\"},\"plot\":{\"id\":\"1003\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"ticker\":{\"id\":\"1220\",\"type\":\"BasicTicker\"},\"y_range_name\":\"hist\"},\"id\":\"1204\",\"type\":\"LinearAxis\"},{\"attributes\":{},\"id\":\"1252\",\"type\":\"Selection\"},{\"attributes\":{\"callback\":null,\"renderers\":[{\"id\":\"1036\",\"type\":\"GlyphRenderer\"},{\"id\":\"1060\",\"type\":\"GlyphRenderer\"},{\"id\":\"1089\",\"type\":\"GlyphRenderer\"},{\"id\":\"1124\",\"type\":\"GlyphRenderer\"},{\"id\":\"1165\",\"type\":\"GlyphRenderer\"}],\"tooltips\":[[\"Height\",\"@x\"],[\"F1 score\",\"@y{0.00}\"]]},\"id\":\"1210\",\"type\":\"HoverTool\"},{\"attributes\":{},\"id\":\"1070\",\"type\":\"UnionRenderers\"},{\"attributes\":{},\"id\":\"1148\",\"type\":\"UnionRenderers\"},{\"attributes\":{},\"id\":\"1251\",\"type\":\"UnionRenderers\"},{\"attributes\":{},\"id\":\"1248\",\"type\":\"Selection\"},{\"attributes\":{\"callback\":null,\"data\":{\"top\":{\"__ndarray__\":\"AAAAAIDyxUAAAAAAAGi1QAAAAAAAOqdAAAAAAABQmUAAAAAAABiNQAAAAAAAuIJAAAAAAADweEAAAAAAAEBzQAAAAAAA4G1AAAAAAACAZkAAAAAAAKBkQAAAAAAAgF9AAAAAAAAAWEAAAAAAAMBYQAAAAAAAgE5AAAAAAAAAUUAAAAAAAIBPQAAAAAAAAExAAAAAAACASEAAAAAAAABDQAAAAAAAgEBAAAAAAAAAQkAAAAAAAAA0QAAAAAAAADlAAAAAAAAAPUAAAAAAAAAxQAAAAAAAADhAAAAAAAAANEAAAAAAAAAwQAAAAAAAAC5AAAAAAAAAJkAAAAAAAAAuQAAAAAAAABRAAAAAAAAAFEAAAAAAAAAQQAAAAAAAAAhAAAAAAAAAFEAAAAAAAAAQQAAAAAAAABhAAAAAAAAAEEAAAAAAAAAAQAAAAAAAABBAAAAAAAAAAEAAAAAAAAAAQAAAAAAAAPA/AAAAAAAA8D8AAAAAAAAAQAAAAAAAAABAAAAAAAAACEAAAAAAAADwPwAAAAAAAPA/AAAAAAAA8D8AAAAAAADwPwAAAAAAAPA/AAAAAAAA8D8AAAAAAADwPwAAAACA8sVAAAAAAABotUAAAAAAADqnQAAAAAAAUJlAAAAAAAAYjUAAAAAAALiCQAAAAAAA8HhAAAAAAABAc0AAAAAAAOBtQAAAAAAAgGZAAAAAAACgZEAAAAAAAIBfQAAAAAAAAFhAAAAAAADAWEAAAAAAAIBOQAAAAAAAAFFAAAAAAACAT0AAAAAAAABMQAAAAAAAgEhAAAAAAAAAQ0AAAAAAAIBAQAAAAAAAAEJAAAAAAAAANEAAAAAAAAA5QAAAAAAAAD1AAAAAAAAAMUAAAAAAAAA4QAAAAAAAADRAAAAAAAAAMEAAAAAAAAAuQAAAAAAAACZAAAAAAAAALkAAAAAAAAAUQAAAAAAAABRAAAAAAAAAEEAAAAAAAAAIQAAAAAAAABRAAAAAAAAAEEAAAAAAAAAYQAAAAAAAABBAAAAAAAAAAEAAAAAAAAAQQAAAAAAAAABAAAAAAAAAAEAAAAAAAADwPwAAAAAAAPA/AAAAAAAAAEAAAAAAAAAAQAAAAAAAAAhAAAAAAAAA8D8AAAAAAADwPwAAAAAAAPA/AAAAAAAA8D8AAAAAAADwPwAAAAAAAPA/AAAAAAAA8D8AAAAAgPLFQAAAAAAAaLVAAAAAAAA6p0AAAAAAAFCZQAAAAAAAGI1AAAAAAAC4gkAAAAAAAPB4QAAAAAAAQHNAAAAAAADgbUAAAAAAAIBmQAAAAAAAoGRAAAAAAACAX0AAAAAAAABYQAAAAAAAwFhAAAAAAACATkAAAAAAAABRQAAAAAAAgE9AAAAAAAAATEAAAAAAAIBIQAAAAAAAAENAAAAAAACAQEAAAAAAAABCQAAAAAAAADRAAAAAAAAAOUAAAAAAAAA9QAAAAAAAADFAAAAAAAAAOEAAAAAAAAA0QAAAAAAAADBAAAAAAAAALkAAAAAAAAAmQAAAAAAAAC5AAAAAAAAAFEAAAAAAAAAUQAAAAAAAABBAAAAAAAAACEAAAAAAAAAUQAAAAAAAABBAAAAAAAAAGEAAAAAAAAAQQAAAAAAAAABAAAAAAAAAEEAAAAAAAAAAQAAAAAAAAABAAAAAAAAA8D8AAAAAAADwPwAAAAAAAABAAAAAAAAAAEAAAAAAAAAIQAAAAAAAAPA/AAAAAAAA8D8AAAAAAADwPwAAAAAAAPA/AAAAAAAA8D8AAAAAAADwPwAAAAAAAPA/AAAAAIDyxUAAAAAAAGi1QAAAAAAAOqdAAAAAAABQmUAAAAAAABiNQAAAAAAAuIJAAAAAAADweEAAAAAAAEBzQAAAAAAA4G1AAAAAAACAZkAAAAAAAKBkQAAAAAAAgF9AAAAAAAAAWEAAAAAAAMBYQAAAAAAAgE5AAAAAAAAAUUAAAAAAAIBPQAAAAAAAAExAAAAAAACASEAAAAAAAABDQAAAAAAAgEBAAAAAAAAAQkAAAAAAAAA0QAAAAAAAADlAAAAAAAAAPUAAAAAAAAAxQAAAAAAAADhAAAAAAAAANEAAAAAAAAAwQAAAAAAAAC5AAAAAAAAAJkAAAAAAAAAuQAAAAAAAABRAAAAAAAAAFEAAAAAAAAAQQAAAAAAAAAhAAAAAAAAAFEAAAAAAAAAQQAAAAAAAABhAAAAAAAAAEEAAAAAAAAAAQAAAAAAAABBAAAAAAAAAAEAAAAAAAAAAQAAAAAAAAPA/AAAAAAAA8D8AAAAAAAAAQAAAAAAAAABAAAAAAAAACEAAAAAAAADwPwAAAAAAAPA/AAAAAAAA8D8AAAAAAADwPwAAAAAAAPA/AAAAAAAA8D8AAAAAAADwPwAAAACA8sVAAAAAAABotUAAAAAAADqnQAAAAAAAUJlAAAAAAAAYjUAAAAAAALiCQAAAAAAA8HhAAAAAAABAc0AAAAAAAOBtQAAAAAAAgGZAAAAAAACgZEAAAAAAAIBfQAAAAAAAAFhAAAAAAADAWEAAAAAAAIBOQAAAAAAAAFFAAAAAAACAT0AAAAAAAABMQAAAAAAAgEhAAAAAAAAAQ0AAAAAAAIBAQAAAAAAAAEJAAAAAAAAANEAAAAAAAAA5QAAAAAAAAD1AAAAAAAAAMUAAAAAAAAA4QAAAAAAAADRAAAAAAAAAMEAAAAAAAAAuQAAAAAAAACZAAAAAAAAALkAAAAAAAAAUQAAAAAAAABRAAAAAAAAAEEAAAAAAAAAIQAAAAAAAABRAAAAAAAAAEEAAAAAAAAAYQAAAAAAAABBAAAAAAAAAAEAAAAAAAAAQQAAAAAAAAABAAAAAAAAAAEAAAAAAAADwPwAAAAAAAPA/AAAAAAAAAEAAAAAAAAAAQAAAAAAAAAhAAAAAAAAA8D8AAAAAAADwPwAAAAAAAPA/AAAAAAAA8D8AAAAAAADwPwAAAAAAAPA/AAAAAAAA8D8AAAAAgPLFQAAAAAAAaLVAAAAAAAA6p0AAAAAAAFCZQAAAAAAAGI1AAAAAAAC4gkAAAAAAAPB4QAAAAAAAQHNAAAAAAADgbUAAAAAAAIBmQAAAAAAAoGRAAAAAAACAX0AAAAAAAABYQAAAAAAAwFhAAAAAAACATkAAAAAAAABRQAAAAAAAgE9AAAAAAAAATEAAAAAAAIBIQAAAAAAAAENAAAAAAACAQEAAAAAAAABCQAAAAAAAADRAAAAAAAAAOUAAAAAAAAA9QAAAAAAAADFAAAAAAAAAOEAAAAAAAAA0QAAAAAAAADBAAAAAAAAALkAAAAAAAAAmQAAAAAAAAC5AAAAAAAAAFEAAAAAAAAAUQAAAAAAAABBAAAAAAAAACEAAAAAAAAAUQAAAAAAAABBAAAAAAAAAGEAAAAAAAAAQQAAAAAAAAABAAAAAAAAAEEAAAAAAAAAAQAAAAAAAAABAAAAAAAAA8D8AAAAAAADwPwAAAAAAAABAAAAAAAAAAEAAAAAAAAAIQAAAAAAAAPA/AAAAAAAA8D8AAAAAAADwPwAAAAAAAPA/AAAAAAAA8D8AAAAAAADwPwAAAAAAAPA/\",\"dtype\":\"float64\",\"shape\":[336]},\"x\":[0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0,16.0,17.0,18.0,19.0,20.0,21.0,22.0,23.0,24.0,25.0,26.0,27.0,28.0,29.0,30.0,31.0,32.0,33.0,34.0,35.0,36.0,37.0,38.0,39.0,40.0,41.0,42.0,43.0,44.0,45.0,46.0,47.0,48.0,51.0,54.0,56.0,57.0,60.0,61.0,71.0,0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0,16.0,17.0,18.0,19.0,20.0,21.0,22.0,23.0,24.0,25.0,26.0,27.0,28.0,29.0,30.0,31.0,32.0,33.0,34.0,35.0,36.0,37.0,38.0,39.0,40.0,41.0,42.0,43.0,44.0,45.0,46.0,47.0,48.0,51.0,54.0,56.0,57.0,60.0,61.0,71.0,0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0,16.0,17.0,18.0,19.0,20.0,21.0,22.0,23.0,24.0,25.0,26.0,27.0,28.0,29.0,30.0,31.0,32.0,33.0,34.0,35.0,36.0,37.0,38.0,39.0,40.0,41.0,42.0,43.0,44.0,45.0,46.0,47.0,48.0,51.0,54.0,56.0,57.0,60.0,61.0,71.0,0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0,16.0,17.0,18.0,19.0,20.0,21.0,22.0,23.0,24.0,25.0,26.0,27.0,28.0,29.0,30.0,31.0,32.0,33.0,34.0,35.0,36.0,37.0,38.0,39.0,40.0,41.0,42.0,43.0,44.0,45.0,46.0,47.0,48.0,51.0,54.0,56.0,57.0,60.0,61.0,71.0,0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0,16.0,17.0,18.0,19.0,20.0,21.0,22.0,23.0,24.0,25.0,26.0,27.0,28.0,29.0,30.0,31.0,32.0,33.0,34.0,35.0,36.0,37.0,38.0,39.0,40.0,41.0,42.0,43.0,44.0,45.0,46.0,47.0,48.0,51.0,54.0,56.0,57.0,60.0,61.0,71.0,0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0,16.0,17.0,18.0,19.0,20.0,21.0,22.0,23.0,24.0,25.0,26.0,27.0,28.0,29.0,30.0,31.0,32.0,33.0,34.0,35.0,36.0,37.0,38.0,39.0,40.0,41.0,42.0,43.0,44.0,45.0,46.0,47.0,48.0,51.0,54.0,56.0,57.0,60.0,61.0,71.0]},\"selected\":{\"id\":\"1252\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1251\",\"type\":\"UnionRenderers\"}},\"id\":\"1205\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"format\":\"0a\"},\"id\":\"1212\",\"type\":\"NumeralTickFormatter\"},{\"attributes\":{\"line_color\":\"#1f77b4\",\"line_width\":2,\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1028\",\"type\":\"Line\"},{\"attributes\":{},\"id\":\"1220\",\"type\":\"BasicTicker\"}],\"root_ids\":[\"1003\"]},\"title\":\"Bokeh Application\",\"version\":\"1.0.4\"}};\n", - " var render_items = [{\"docid\":\"2b9ed80b-2ed8-4c88-bc31-0b2e9e229758\",\"roots\":{\"1003\":\"35cf8d8a-e9de-42ee-911e-fcd3c98e5c78\"}}];\n", - " root.Bokeh.embed.embed_items_notebook(docs_json, render_items);\n", - "\n", - " }\n", - " if (root.Bokeh !== undefined) {\n", - " embed_document(root);\n", - " } else {\n", - " var attempts = 0;\n", - " var timer = setInterval(function(root) {\n", - " if (root.Bokeh !== undefined) {\n", - " embed_document(root);\n", - " clearInterval(timer);\n", - " }\n", - " attempts++;\n", - " if (attempts > 100) {\n", - " console.log(\"Bokeh: ERROR: Unable to run BokehJS code because BokehJS library is missing\");\n", - " clearInterval(timer);\n", - " }\n", - " }, 10, root)\n", - " }\n", - "})(window);" - ], - "application/vnd.bokehjs_exec.v0+json": "" - }, - "metadata": { - "application/vnd.bokehjs_exec.v0+json": { - "id": "1003" - } - }, - "output_type": "display_data" - } - ], - "source": [ - "height = 400\n", - "width = 900\n", - "_FONT_SIZE = \"14pt\"\n", - "\n", - "# title = \"F1 by height on OntoNotes constituent labeling\"\n", - "# _X_LABEL = \"Constituent Height\"\n", - "# _X_RANGE = [1.5,20.5]\n", - "# _Y_RANGE = [0,1]\n", - "# title = \"F1 by span distance on OntoNotes SRL\"\n", - "# _X_LABEL = \"Span separation distance (tokens)\"\n", - "# _X_RANGE = [-0.5, 15.5]\n", - "# _Y_RANGE = [0.5,1]\n", - "# _X_LABEL = \"Span separation distance (tokens)\"\n", - "# _X_RANGE = [-0.5, 15.5]\n", - "# _Y_RANGE = [0.5,1]\n", - "# title = \"F1 by span distance on dependency labeling\"\n", - "_X_LABEL = \"Span separation distance (tokens)\"\n", - "_X_RANGE = [-0.5, 15.5]\n", - "_Y_RANGE = [0.4,1.05]\n", - "\n", - "# def _make_plot_legend_name(exp_type, tag):\n", - "# if exp_type == \"elmo-full\":\n", - "# return \"Full ELMo\"\n", - "# elif exp_type == \"elmo-chars\":\n", - "# return f\"Lex. ({tag})\"\n", - "# else:\n", - "# raise ValueError(f\"Unrecognized experiment: ({exp_type}, {tag})\")\n", - "\n", - "col_keys = [\n", - " (\"elmo-chars\", \"base\", \"Lex.\", \"diamond\"),\n", - " (\"elmo-chars\", \"cnn1\", \"CNN1\", \"triangle\"),\n", - " (\"elmo-chars\", \"cnn2\", \"CNN2\", \"inverted_triangle\"),\n", - " (\"elmo-ortho\", \"base\", \"Ortho.\", \"square\"),\n", - " (\"elmo-full\", \"base\", \"Full\", \"circle\"),\n", - "]\n", - "\n", - "plot_df['col_key'] = list(zip(plot_df['exp_type'], plot_df['tag']))\n", - " \n", - "_SCORE_COL=\"f1_score\"\n", - "_ERROR_COL=\"f1_errn95\"\n", - "\n", - "tools = \"save,reset\"\n", - "\n", - "palette = bokeh.palettes.Category20[20]\n", - "p = bp.figure(x_range=_X_RANGE, y_range=_Y_RANGE, \n", - " width=width, height=height,\n", - " tools=tools)\n", - "crs = []\n", - "# gb = plot_df.groupby(by=[\"exp_type\", \"tag\", \"display_col\"])\n", - "# for i, ((exp_type, tag, name), idx) in enumerate(gb.groups.items()):\n", - "for i, ck in enumerate(col_keys):\n", - " ds = plot_df[plot_df['col_key'] == ck[:2]]\n", - " exp_type = ck[0]\n", - " et_key = exp_type + (f\"-{tag}\" if tag != \"base\" else \"\")\n", - "# x = plot_df.loc[idx, \"stratum_key\"]\n", - "# y = plot_df.loc[idx, _SCORE_COL]\n", - "# e = plot_df.loc[idx, _ERROR_COL]\n", - " x = ds[\"stratum_key\"]\n", - " y = ds[_SCORE_COL]\n", - " e = ds[_ERROR_COL]\n", - " c = palette[2*i]\n", - "# display_name = _make_plot_legend_name(exp_type, tag) + \" \"\n", - "# display_name = ck[2]\n", - " p.line(x=x, y=y, color=c, line_width=2)\n", - " cr = p.scatter(x=x, y=y, color=c, size=12, hover_fill_color=\"Gray\",\n", - " legend=ck[2], marker=ck[3])\n", - " crs.append(cr)\n", - " ds = bokeh.models.ColumnDataSource(data=dict(x=x, upper=y+e, lower=y-e))\n", - "# error_bars = bokeh.models.Whisker(base='x', upper='upper', lower='lower',\n", - "# line_color=c,\n", - "# source=ds)\n", - "# p.add_layout(error_bars)\n", - " error_band = bokeh.models.Band(base='x', upper='upper', lower='lower',\n", - " source=ds, level='underlay',\n", - " fill_alpha=0.4, line_width=1,\n", - " line_color=palette[2*i],\n", - " fill_color=palette[2*i+1])\n", - " p.add_layout(error_band)\n", - "\n", - "p.yaxis.bounds = (0,1)\n", - "\n", - "##\n", - "# Overlay histogram at bottom of the plot (this looks nice)\n", - "counts = plot_df['tp_count'] + plot_df['fn_count']\n", - "strata = plot_df['stratum_key']\n", - "hist_height = 0.3\n", - "p.extra_y_ranges = {\"hist\": bokeh.models.Range1d(min(counts), \n", - " max(counts)/hist_height)}\n", - "p.add_layout(bokeh.models.LinearAxis(y_range_name=\"hist\",\n", - " bounds=(min(counts), max(counts))), \"right\")\n", - "p.vbar(x=strata, top=counts, width=0.9,\n", - " y_range_name='hist', color=\"Gray\")\n", - "\n", - "# Add fancy hover tool\n", - "tooltips = [\n", - " (\"Height\", \"@x\"),\n", - " (\"F1 score\", \"@y{0.00}\"),\n", - "]\n", - "p.add_tools(bokeh.models.HoverTool(tooltips=tooltips, renderers=crs, \n", - "# mode='vline',\n", - " ))\n", - "p.xaxis.axis_label = _X_LABEL\n", - "p.yaxis[0].axis_label = \"F1 Score\"\n", - "p.yaxis[1].axis_label = \"\"\n", - "p.yaxis[1].formatter = bokeh.models.NumeralTickFormatter(format=\"0a\")\n", - "p.legend.orientation = \"horizontal\"\n", - "# p.legend.location = \"bottom_right\"\n", - "# p.legend.background_fill_alpha = 0.0\n", - "# p.legend.border_line_alpha = 0\n", - "\n", - "p.yaxis.major_label_text_font_size = \"13pt\"\n", - "p.xaxis.major_label_text_font_size = \"13pt\"\n", - "p.xaxis.major_label_text_font_size = _FONT_SIZE\n", - "p.xaxis.axis_label_text_font_size = _FONT_SIZE\n", - "p.yaxis.axis_label_text_font_size = _FONT_SIZE\n", - "# p.legend.orientation = \"horizontal\"\n", - "p.legend.background_fill_color = None\n", - "p.legend.border_line_color = None\n", - "p.legend.label_text_font_size = _FONT_SIZE\n", - "\n", - "p.min_border = 0\n", - "\n", - "bp.show(p)" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - "
\n", - " \n", - " Loading BokehJS ...\n", - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": [ - "\n", - "(function(root) {\n", - " function now() {\n", - " return new Date();\n", - " }\n", - "\n", - " var force = true;\n", - "\n", - " if (typeof (root._bokeh_onload_callbacks) === \"undefined\" || force === true) {\n", - " root._bokeh_onload_callbacks = [];\n", - " root._bokeh_is_loading = undefined;\n", - " }\n", - "\n", - " var JS_MIME_TYPE = 'application/javascript';\n", - " var HTML_MIME_TYPE = 'text/html';\n", - " var EXEC_MIME_TYPE = 'application/vnd.bokehjs_exec.v0+json';\n", - " var CLASS_NAME = 'output_bokeh rendered_html';\n", - "\n", - " /**\n", - " * Render data to the DOM node\n", - " */\n", - " function render(props, node) {\n", - " var script = document.createElement(\"script\");\n", - " node.appendChild(script);\n", - " }\n", - "\n", - " /**\n", - " * Handle when an output is cleared or removed\n", - " */\n", - " function handleClearOutput(event, handle) {\n", - " var cell = handle.cell;\n", - "\n", - " var id = cell.output_area._bokeh_element_id;\n", - " var server_id = cell.output_area._bokeh_server_id;\n", - " // Clean up Bokeh references\n", - " if (id != null && id in Bokeh.index) {\n", - " Bokeh.index[id].model.document.clear();\n", - " delete Bokeh.index[id];\n", - " }\n", - "\n", - " if (server_id !== undefined) {\n", - " // Clean up Bokeh references\n", - " var cmd = \"from bokeh.io.state import curstate; print(curstate().uuid_to_server['\" + server_id + \"'].get_sessions()[0].document.roots[0]._id)\";\n", - " cell.notebook.kernel.execute(cmd, {\n", - " iopub: {\n", - " output: function(msg) {\n", - " var id = msg.content.text.trim();\n", - " if (id in Bokeh.index) {\n", - " Bokeh.index[id].model.document.clear();\n", - " delete Bokeh.index[id];\n", - " }\n", - " }\n", - " }\n", - " });\n", - " // Destroy server and session\n", - " var cmd = \"import bokeh.io.notebook as ion; ion.destroy_server('\" + server_id + \"')\";\n", - " cell.notebook.kernel.execute(cmd);\n", - " }\n", - " }\n", - "\n", - " /**\n", - " * Handle when a new output is added\n", - " */\n", - " function handleAddOutput(event, handle) {\n", - " var output_area = handle.output_area;\n", - " var output = handle.output;\n", - "\n", - " // limit handleAddOutput to display_data with EXEC_MIME_TYPE content only\n", - " if ((output.output_type != \"display_data\") || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n", - " return\n", - " }\n", - "\n", - " var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n", - "\n", - " if (output.metadata[EXEC_MIME_TYPE][\"id\"] !== undefined) {\n", - " toinsert[toinsert.length - 1].firstChild.textContent = output.data[JS_MIME_TYPE];\n", - " // store reference to embed id on output_area\n", - " output_area._bokeh_element_id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n", - " }\n", - " if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n", - " var bk_div = document.createElement(\"div\");\n", - " bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n", - " var script_attrs = bk_div.children[0].attributes;\n", - " for (var i = 0; i < script_attrs.length; i++) {\n", - " toinsert[toinsert.length - 1].firstChild.setAttribute(script_attrs[i].name, script_attrs[i].value);\n", - " }\n", - " // store reference to server id on output_area\n", - " output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n", - " }\n", - " }\n", - "\n", - " function register_renderer(events, OutputArea) {\n", - "\n", - " function append_mime(data, metadata, element) {\n", - " // create a DOM node to render to\n", - " var toinsert = this.create_output_subarea(\n", - " metadata,\n", - " CLASS_NAME,\n", - " EXEC_MIME_TYPE\n", - " );\n", - " this.keyboard_manager.register_events(toinsert);\n", - " // Render to node\n", - " var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n", - " render(props, toinsert[toinsert.length - 1]);\n", - " element.append(toinsert);\n", - " return toinsert\n", - " }\n", - "\n", - " /* Handle when an output is cleared or removed */\n", - " events.on('clear_output.CodeCell', handleClearOutput);\n", - " events.on('delete.Cell', handleClearOutput);\n", - "\n", - " /* Handle when a new output is added */\n", - " events.on('output_added.OutputArea', handleAddOutput);\n", - "\n", - " /**\n", - " * Register the mime type and append_mime function with output_area\n", - " */\n", - " OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n", - " /* Is output safe? */\n", - " safe: true,\n", - " /* Index of renderer in `output_area.display_order` */\n", - " index: 0\n", - " });\n", - " }\n", - "\n", - " // register the mime type if in Jupyter Notebook environment and previously unregistered\n", - " if (root.Jupyter !== undefined) {\n", - " var events = require('base/js/events');\n", - " var OutputArea = require('notebook/js/outputarea').OutputArea;\n", - "\n", - " if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n", - " register_renderer(events, OutputArea);\n", - " }\n", - " }\n", - "\n", - " \n", - " if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n", - " root._bokeh_timeout = Date.now() + 5000;\n", - " root._bokeh_failed_load = false;\n", - " }\n", - "\n", - " var NB_LOAD_WARNING = {'data': {'text/html':\n", - " \"
\\n\"+\n", - " \"

\\n\"+\n", - " \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n", - " \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n", - " \"

\\n\"+\n", - " \"
    \\n\"+\n", - " \"
  • re-rerun `output_notebook()` to attempt to load from CDN again, or
  • \\n\"+\n", - " \"
  • use INLINE resources instead, as so:
  • \\n\"+\n", - " \"
\\n\"+\n", - " \"\\n\"+\n", - " \"from bokeh.resources import INLINE\\n\"+\n", - " \"output_notebook(resources=INLINE)\\n\"+\n", - " \"\\n\"+\n", - " \"
\"}};\n", - "\n", - " function display_loaded() {\n", - " var el = document.getElementById(\"2311\");\n", - " if (el != null) {\n", - " el.textContent = \"BokehJS is loading...\";\n", - " }\n", - " if (root.Bokeh !== undefined) {\n", - " if (el != null) {\n", - " el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n", - " }\n", - " } else if (Date.now() < root._bokeh_timeout) {\n", - " setTimeout(display_loaded, 100)\n", - " }\n", - " }\n", - "\n", - "\n", - " function run_callbacks() {\n", - " try {\n", - " root._bokeh_onload_callbacks.forEach(function(callback) { callback() });\n", - " }\n", - " finally {\n", - " delete root._bokeh_onload_callbacks\n", - " }\n", - " console.info(\"Bokeh: all callbacks have finished\");\n", - " }\n", - "\n", - " function load_libs(js_urls, callback) {\n", - " root._bokeh_onload_callbacks.push(callback);\n", - " if (root._bokeh_is_loading > 0) {\n", - " console.log(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n", - " return null;\n", - " }\n", - " if (js_urls == null || js_urls.length === 0) {\n", - " run_callbacks();\n", - " return null;\n", - " }\n", - " console.log(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n", - " root._bokeh_is_loading = js_urls.length;\n", - " for (var i = 0; i < js_urls.length; i++) {\n", - " var url = js_urls[i];\n", - " var s = document.createElement('script');\n", - " s.src = url;\n", - " s.async = false;\n", - " s.onreadystatechange = s.onload = function() {\n", - " root._bokeh_is_loading--;\n", - " if (root._bokeh_is_loading === 0) {\n", - " console.log(\"Bokeh: all BokehJS libraries loaded\");\n", - " run_callbacks()\n", - " }\n", - " };\n", - " s.onerror = function() {\n", - " console.warn(\"failed to load library \" + url);\n", - " };\n", - " console.log(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", - " document.getElementsByTagName(\"head\")[0].appendChild(s);\n", - " }\n", - " };var element = document.getElementById(\"2311\");\n", - " if (element == null) {\n", - " console.log(\"Bokeh: ERROR: autoload.js configured with elementid '2311' but no matching script tag was found. \")\n", - " return false;\n", - " }\n", - "\n", - " var js_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-1.0.4.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.0.4.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.0.4.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-gl-1.0.4.min.js\"];\n", - "\n", - " var inline_js = [\n", - " function(Bokeh) {\n", - " Bokeh.set_log_level(\"info\");\n", - " },\n", - " \n", - " function(Bokeh) {\n", - " \n", - " },\n", - " function(Bokeh) {\n", - " console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/release/bokeh-1.0.4.min.css\");\n", - " Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/release/bokeh-1.0.4.min.css\");\n", - " console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.0.4.min.css\");\n", - " Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.0.4.min.css\");\n", - " console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/release/bokeh-tables-1.0.4.min.css\");\n", - " Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.0.4.min.css\");\n", - " }\n", - " ];\n", - "\n", - " function run_inline_js() {\n", - " \n", - " if ((root.Bokeh !== undefined) || (force === true)) {\n", - " for (var i = 0; i < inline_js.length; i++) {\n", - " inline_js[i].call(root, root.Bokeh);\n", - " }if (force === true) {\n", - " display_loaded();\n", - " }} else if (Date.now() < root._bokeh_timeout) {\n", - " setTimeout(run_inline_js, 100);\n", - " } else if (!root._bokeh_failed_load) {\n", - " console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n", - " root._bokeh_failed_load = true;\n", - " } else if (force !== true) {\n", - " var cell = $(document.getElementById(\"2311\")).parents('.cell').data().cell;\n", - " cell.output_area.append_execute_result(NB_LOAD_WARNING)\n", - " }\n", - "\n", - " }\n", - "\n", - " if (root._bokeh_is_loading === 0) {\n", - " console.log(\"Bokeh: BokehJS loaded, going straight to plotting\");\n", - " run_inline_js();\n", - " } else {\n", - " load_libs(js_urls, function() {\n", - " console.log(\"Bokeh: BokehJS plotting callback run at\", now());\n", - " run_inline_js();\n", - " });\n", - " }\n", - "}(window));" - ], - "application/vnd.bokehjs_load.v0+json": "\n(function(root) {\n function now() {\n return new Date();\n }\n\n var force = true;\n\n if (typeof (root._bokeh_onload_callbacks) === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\n \n\n \n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n var NB_LOAD_WARNING = {'data': {'text/html':\n \"
\\n\"+\n \"

\\n\"+\n \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n \"

\\n\"+\n \"
    \\n\"+\n \"
  • re-rerun `output_notebook()` to attempt to load from CDN again, or
  • \\n\"+\n \"
  • use INLINE resources instead, as so:
  • \\n\"+\n \"
\\n\"+\n \"\\n\"+\n \"from bokeh.resources import INLINE\\n\"+\n \"output_notebook(resources=INLINE)\\n\"+\n \"\\n\"+\n \"
\"}};\n\n function display_loaded() {\n var el = document.getElementById(\"2311\");\n if (el != null) {\n el.textContent = \"BokehJS is loading...\";\n }\n if (root.Bokeh !== undefined) {\n if (el != null) {\n el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n }\n } else if (Date.now() < root._bokeh_timeout) {\n setTimeout(display_loaded, 100)\n }\n }\n\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) { callback() });\n }\n finally {\n delete root._bokeh_onload_callbacks\n }\n console.info(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(js_urls, callback) {\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.log(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls == null || js_urls.length === 0) {\n run_callbacks();\n return null;\n }\n console.log(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n root._bokeh_is_loading = js_urls.length;\n for (var i = 0; i < js_urls.length; i++) {\n var url = js_urls[i];\n var s = document.createElement('script');\n s.src = url;\n s.async = false;\n s.onreadystatechange = s.onload = function() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.log(\"Bokeh: all BokehJS libraries loaded\");\n run_callbacks()\n }\n };\n s.onerror = function() {\n console.warn(\"failed to load library \" + url);\n };\n console.log(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.getElementsByTagName(\"head\")[0].appendChild(s);\n }\n };var element = document.getElementById(\"2311\");\n if (element == null) {\n console.log(\"Bokeh: ERROR: autoload.js configured with elementid '2311' but no matching script tag was found. \")\n return false;\n }\n\n var js_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-1.0.4.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.0.4.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.0.4.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-gl-1.0.4.min.js\"];\n\n var inline_js = [\n function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\n \n function(Bokeh) {\n \n },\n function(Bokeh) {\n console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/release/bokeh-1.0.4.min.css\");\n Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/release/bokeh-1.0.4.min.css\");\n console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.0.4.min.css\");\n Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.0.4.min.css\");\n console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/release/bokeh-tables-1.0.4.min.css\");\n Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.0.4.min.css\");\n }\n ];\n\n function run_inline_js() {\n \n if ((root.Bokeh !== undefined) || (force === true)) {\n for (var i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }if (force === true) {\n display_loaded();\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n } else if (force !== true) {\n var cell = $(document.getElementById(\"2311\")).parents('.cell').data().cell;\n cell.output_area.append_execute_result(NB_LOAD_WARNING)\n }\n\n }\n\n if (root._bokeh_is_loading === 0) {\n console.log(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(js_urls, function() {\n console.log(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));" - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "import bokeh\n", - "import bokeh.plotting as bp\n", - "bp.output_notebook()\n", - "\n", - "import datetime\n", - "import socket\n", - "def get_compact_timestamp():\n", - " now = datetime.datetime.now()\n", - " return now.strftime(\"%Y%m%d.%H%M%S\")\n", - "\n", - "def _save_figure_to_bucket(fig, name, title=None, export_format=\"html\"):\n", - " now = get_compact_timestamp()\n", - " fname = f\"{name}.{now:s}.{export_format}\"\n", - " title = title or name\n", - " if fname.endswith('.png'):\n", - " bokeh.io.export_png(p, os.path.join(\"/tmp\", fname))\n", - " else:\n", - " bp.save(p, os.path.join(\"/tmp\", fname), title=title, \n", - " resources=bokeh.resources.CDN)\n", - " hostname = socket.gethostname()\n", - " !gsutil cp /tmp/$fname gs://edge-probing/$hostname/plots/$fname\n", - " !gsutil acl ch -u AllUsers:R gs://edge-probing/$hostname/plots/$fname\n", - " url = f\"https://storage.googleapis.com/edge-probing/{hostname}/plots/{fname}\"\n", - " print(f\"Public URL: {url}\")\n", - " return url" - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Copying file:///tmp/scores_by_distance.20190504.001735.html [Content-Type=text/html]...\n", - "/ [1 files][ 44.8 KiB/ 44.8 KiB] \n", - "Operation completed over 1 objects/44.8 KiB. \n", - "Updated ACL on gs://edge-probing/iftenney/plots/scores_by_distance.20190504.001735.html\n", - "Public URL: https://storage.googleapis.com/edge-probing/iftenney/plots/scores_by_distance.20190504.001735.html\n" - ] - }, - { - "data": { - "text/plain": [ - "'https://storage.googleapis.com/edge-probing/iftenney/plots/scores_by_distance.20190504.001735.html'" - ] - }, - "execution_count": 24, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "_save_figure_to_bucket(p, name=\"scores_by_distance\",\n", - " title=\"Scores by distance\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "p1 = p" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "scrolled": true - }, - "outputs": [], - "source": [ - "mask = (df.split == \"val\")\n", - "mask &= (df.stratifier == \"info.height\") & (df.task == \"constituent-ontonotes\")\n", - "mask &= df['exp_type'].map(lambda t: t in {'elmo-chars', 'elmo-full', 'elmo-ortho', 'openai-cat'})\n", - "sheet_df = df[mask].pivot(index=\"stratum_key\", columns=\"display_col\", values=\"f1_score\")\n", - "sheet_df = sheet_df.reindex(sorted(sheet_df.columns, \n", - " key=exp_type_sort_key), axis=1)\n", - "sheet_df = sheet_df.reindex(sorted(sheet_df.index), axis=0)\n", - "# sheet_df\n", - "print(sheet_df.to_csv())" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "scrolled": true - }, - "outputs": [], - "source": [ - "sheet_df = df[mask].pivot(index=\"stratum_key\", columns=\"display_col\", values=\"f1_errn95\")\n", - "sheet_df = sheet_df.reindex(sorted(sheet_df.columns, \n", - " key=exp_type_sort_key), axis=1)\n", - "sheet_df = sheet_df.reindex(sorted(sheet_df.index), axis=0)\n", - "# sheet_df\n", - "print(sheet_df.to_csv())" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Plot by span distance\n", - "\n", - "Absolute distance (in number of tokens under model tokenization) between midpoint of `span1` and midpoint of `span2`." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "df.columns" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "df['task'].unique()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "mask = df.stratifier.notnull() & (df.task == \"srl-conll2012\") & (df.split == \"val\")\n", - "mask &= df['exp_type'].map(lambda t: t in {'elmo-chars', 'elmo-full', 'elmo-ortho', 'openai-cat'})\n", - "sheet_df = df[mask].pivot(index=\"stratum_key\", columns=\"display_col\", values=\"f1_score\")\n", - "sheet_df = sheet_df.reindex(sorted(sheet_df.columns, \n", - " key=exp_type_sort_key), axis=1)\n", - "sheet_df = sheet_df.reindex(sorted(sheet_df.index), axis=0)\n", - "# sheet_df\n", - "print(sheet_df.to_csv())" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Plot by label for Relations" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "mask = (df.task == \"rel-semeval\") & (df.split == \"val\")\n", - "mask &= df.label.map(is_positive_relation)\n", - "sheet_df = df[mask].pivot(index=\"label\", columns=\"exp_type\", values=\"f1_score\")\n", - "sheet_df = sheet_df.reindex(sorted(sheet_df.columns, \n", - " key=exp_type_sort_key), axis=1)\n", - "sheet_df = sheet_df.reindex(sorted(sheet_df.index,\n", - " key=task_sort_key), axis=0)\n", - "# sheet_df\n", - "print(sheet_df.to_csv())" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Plot by label for SRL core, non-core" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "mask = df.label.map(is_core_or_noncore) & (df.task == \"srl-conll2012\") & (df.split == \"val\")\n", - "sheet_df = df[mask].pivot(index=\"label\", columns=\"exp_type\", values=\"f1_score\")\n", - "sheet_df = sheet_df.reindex(sorted(sheet_df.columns, \n", - " key=exp_type_sort_key), axis=1)\n", - "sheet_df = sheet_df.reindex(sorted(sheet_df.index,\n", - " key=task_sort_key), axis=0)\n", - "# sheet_df\n", - "print(sheet_df.to_csv())" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "df[mask].exp_type.unique()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "plot_df = df[df.label.map(is_core_role) & (df.task == \"srl-conll2012\")].copy()\n", - "\n", - "_SCORE_COL=\"f1_score\"\n", - "plot_df['row_key'] = list(zip(plot_df['task'], plot_df['exp_type']))\n", - "plot_df['fmt_score'] = plot_df[_SCORE_COL].map(\n", - " lambda s: \"{:.02f}\".format(s)\n", - ")\n", - "print(\"Found %s entries\" % len(plot_df))\n", - "long_ds = bokeh.models.ColumnDataSource(data=plot_df)\n", - "\n", - "factor_range = bokeh.models.FactorRange(*categories, range_padding=0.5,\n", - " range_padding_units='absolute')\n", - "tools = \"save,reset\"\n", - "\n", - "p = bp.figure(x_range=factor_range, y_range=[0,1],\n", - " width=1250, tools=tools)\n", - "p.vbar(x='row_key', top=_SCORE_COL, width=0.95,\n", - " fill_color=fill_cmap,\n", - " line_color=\"Gray\", source=long_ds)\n", - "label_kw = dict(text_align=\"right\", text_baseline=\"middle\", y_offset=-3,\n", - " text_font_size=\"11pt\", angle=90, angle_units='deg')\n", - "score_labels = bokeh.models.LabelSet(x='row_key', y=_SCORE_COL,\n", - " text=\"fmt_score\",\n", - " source=long_ds, **label_kw)\n", - "p.add_layout(score_labels)\n", - "p.xaxis.major_label_orientation = 1\n", - "p.yaxis.bounds = (0,1)\n", - "\n", - "bp.show(p)" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "jiant", - "language": "python", - "name": "jiant" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.6.8" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/probing/analysis_edgeprobe_standard.ipynb b/probing/analysis_edgeprobe_standard.ipynb deleted file mode 100644 index 7a95bb649..000000000 --- a/probing/analysis_edgeprobe_standard.ipynb +++ /dev/null @@ -1,2262 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": { - "nbpresent": { - "id": "a1648a5d-023c-4322-9ced-16ff25bf8874" - } - }, - "source": [ - "# Edgeprobe Aggregate Analysis\n", - "\n", - "This notebook is intended to be run on the output of the [`analyze_runs.py`](analyze_runs.py) script; run that on a folder of experiments to produce a `scores.tsv` file that can be loaded here." - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "nbpresent": { - "id": "a527345e-7434-4e96-ae52-51b5b79be75e" - } - }, - "outputs": [], - "source": [ - "import sys, os, re, json\n", - "from importlib import reload\n", - "import itertools\n", - "import collections\n", - "\n", - "import numpy as np\n", - "import pandas as pd\n", - "\n", - "import analysis\n", - "reload(analysis)\n", - "\n", - "tasks = analysis.TASKS\n", - "exp_types = analysis.EXP_TYPES\n", - "palette = analysis.EXP_PALETTE\n", - "\n", - "task_sort_key = analysis.task_sort_key\n", - "exp_type_sort_key = analysis.exp_type_sort_key\n", - "\n", - "from scipy.special import logsumexp\n", - "from scipy.stats import entropy\n", - "\n", - "def softmax(x, axis=None):\n", - " return np.exp(x - logsumexp(x, axis=axis, keepdims=True))" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": { - "nbpresent": { - "id": "1bca01a3-7e20-4ffa-b8d7-764ef2f41929" - } - }, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - "
\n", - " \n", - " Loading BokehJS ...\n", - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": [ - "\n", - "(function(root) {\n", - " function now() {\n", - " return new Date();\n", - " }\n", - "\n", - " var force = true;\n", - "\n", - " if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n", - " root._bokeh_onload_callbacks = [];\n", - " root._bokeh_is_loading = undefined;\n", - " }\n", - "\n", - " var JS_MIME_TYPE = 'application/javascript';\n", - " var HTML_MIME_TYPE = 'text/html';\n", - " var EXEC_MIME_TYPE = 'application/vnd.bokehjs_exec.v0+json';\n", - " var CLASS_NAME = 'output_bokeh rendered_html';\n", - "\n", - " /**\n", - " * Render data to the DOM node\n", - " */\n", - " function render(props, node) {\n", - " var script = document.createElement(\"script\");\n", - " node.appendChild(script);\n", - " }\n", - "\n", - " /**\n", - " * Handle when an output is cleared or removed\n", - " */\n", - " function handleClearOutput(event, handle) {\n", - " var cell = handle.cell;\n", - "\n", - " var id = cell.output_area._bokeh_element_id;\n", - " var server_id = cell.output_area._bokeh_server_id;\n", - " // Clean up Bokeh references\n", - " if (id != null && id in Bokeh.index) {\n", - " Bokeh.index[id].model.document.clear();\n", - " delete Bokeh.index[id];\n", - " }\n", - "\n", - " if (server_id !== undefined) {\n", - " // Clean up Bokeh references\n", - " var cmd = \"from bokeh.io.state import curstate; print(curstate().uuid_to_server['\" + server_id + \"'].get_sessions()[0].document.roots[0]._id)\";\n", - " cell.notebook.kernel.execute(cmd, {\n", - " iopub: {\n", - " output: function(msg) {\n", - " var id = msg.content.text.trim();\n", - " if (id in Bokeh.index) {\n", - " Bokeh.index[id].model.document.clear();\n", - " delete Bokeh.index[id];\n", - " }\n", - " }\n", - " }\n", - " });\n", - " // Destroy server and session\n", - " var cmd = \"import bokeh.io.notebook as ion; ion.destroy_server('\" + server_id + \"')\";\n", - " cell.notebook.kernel.execute(cmd);\n", - " }\n", - " }\n", - "\n", - " /**\n", - " * Handle when a new output is added\n", - " */\n", - " function handleAddOutput(event, handle) {\n", - " var output_area = handle.output_area;\n", - " var output = handle.output;\n", - "\n", - " // limit handleAddOutput to display_data with EXEC_MIME_TYPE content only\n", - " if ((output.output_type != \"display_data\") || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n", - " return\n", - " }\n", - "\n", - " var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n", - "\n", - " if (output.metadata[EXEC_MIME_TYPE][\"id\"] !== undefined) {\n", - " toinsert[toinsert.length - 1].firstChild.textContent = output.data[JS_MIME_TYPE];\n", - " // store reference to embed id on output_area\n", - " output_area._bokeh_element_id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n", - " }\n", - " if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n", - " var bk_div = document.createElement(\"div\");\n", - " bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n", - " var script_attrs = bk_div.children[0].attributes;\n", - " for (var i = 0; i < script_attrs.length; i++) {\n", - " toinsert[toinsert.length - 1].firstChild.setAttribute(script_attrs[i].name, script_attrs[i].value);\n", - " }\n", - " // store reference to server id on output_area\n", - " output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n", - " }\n", - " }\n", - "\n", - " function register_renderer(events, OutputArea) {\n", - "\n", - " function append_mime(data, metadata, element) {\n", - " // create a DOM node to render to\n", - " var toinsert = this.create_output_subarea(\n", - " metadata,\n", - " CLASS_NAME,\n", - " EXEC_MIME_TYPE\n", - " );\n", - " this.keyboard_manager.register_events(toinsert);\n", - " // Render to node\n", - " var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n", - " render(props, toinsert[toinsert.length - 1]);\n", - " element.append(toinsert);\n", - " return toinsert\n", - " }\n", - "\n", - " /* Handle when an output is cleared or removed */\n", - " events.on('clear_output.CodeCell', handleClearOutput);\n", - " events.on('delete.Cell', handleClearOutput);\n", - "\n", - " /* Handle when a new output is added */\n", - " events.on('output_added.OutputArea', handleAddOutput);\n", - "\n", - " /**\n", - " * Register the mime type and append_mime function with output_area\n", - " */\n", - " OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n", - " /* Is output safe? */\n", - " safe: true,\n", - " /* Index of renderer in `output_area.display_order` */\n", - " index: 0\n", - " });\n", - " }\n", - "\n", - " // register the mime type if in Jupyter Notebook environment and previously unregistered\n", - " if (root.Jupyter !== undefined) {\n", - " var events = require('base/js/events');\n", - " var OutputArea = require('notebook/js/outputarea').OutputArea;\n", - "\n", - " if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n", - " register_renderer(events, OutputArea);\n", - " }\n", - " }\n", - "\n", - " \n", - " if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n", - " root._bokeh_timeout = Date.now() + 5000;\n", - " root._bokeh_failed_load = false;\n", - " }\n", - "\n", - " var NB_LOAD_WARNING = {'data': {'text/html':\n", - " \"
\\n\"+\n", - " \"

\\n\"+\n", - " \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n", - " \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n", - " \"

\\n\"+\n", - " \"
    \\n\"+\n", - " \"
  • re-rerun `output_notebook()` to attempt to load from CDN again, or
  • \\n\"+\n", - " \"
  • use INLINE resources instead, as so:
  • \\n\"+\n", - " \"
\\n\"+\n", - " \"\\n\"+\n", - " \"from bokeh.resources import INLINE\\n\"+\n", - " \"output_notebook(resources=INLINE)\\n\"+\n", - " \"\\n\"+\n", - " \"
\"}};\n", - "\n", - " function display_loaded() {\n", - " var el = document.getElementById(\"1001\");\n", - " if (el != null) {\n", - " el.textContent = \"BokehJS is loading...\";\n", - " }\n", - " if (root.Bokeh !== undefined) {\n", - " if (el != null) {\n", - " el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n", - " }\n", - " } else if (Date.now() < root._bokeh_timeout) {\n", - " setTimeout(display_loaded, 100)\n", - " }\n", - " }\n", - "\n", - "\n", - " function run_callbacks() {\n", - " try {\n", - " root._bokeh_onload_callbacks.forEach(function(callback) {\n", - " if (callback != null)\n", - " callback();\n", - " });\n", - " } finally {\n", - " delete root._bokeh_onload_callbacks\n", - " }\n", - " console.debug(\"Bokeh: all callbacks have finished\");\n", - " }\n", - "\n", - " function load_libs(css_urls, js_urls, callback) {\n", - " if (css_urls == null) css_urls = [];\n", - " if (js_urls == null) js_urls = [];\n", - "\n", - " root._bokeh_onload_callbacks.push(callback);\n", - " if (root._bokeh_is_loading > 0) {\n", - " console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n", - " return null;\n", - " }\n", - " if (js_urls == null || js_urls.length === 0) {\n", - " run_callbacks();\n", - " return null;\n", - " }\n", - " console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n", - " root._bokeh_is_loading = css_urls.length + js_urls.length;\n", - "\n", - " function on_load() {\n", - " root._bokeh_is_loading--;\n", - " if (root._bokeh_is_loading === 0) {\n", - " console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n", - " run_callbacks()\n", - " }\n", - " }\n", - "\n", - " function on_error() {\n", - " console.error(\"failed to load \" + url);\n", - " }\n", - "\n", - " for (var i = 0; i < css_urls.length; i++) {\n", - " var url = css_urls[i];\n", - " const element = document.createElement(\"link\");\n", - " element.onload = on_load;\n", - " element.onerror = on_error;\n", - " element.rel = \"stylesheet\";\n", - " element.type = \"text/css\";\n", - " element.href = url;\n", - " console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n", - " document.body.appendChild(element);\n", - " }\n", - "\n", - " for (var i = 0; i < js_urls.length; i++) {\n", - " var url = js_urls[i];\n", - " var element = document.createElement('script');\n", - " element.onload = on_load;\n", - " element.onerror = on_error;\n", - " element.async = false;\n", - " element.src = url;\n", - " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", - " document.head.appendChild(element);\n", - " }\n", - " };var element = document.getElementById(\"1001\");\n", - " if (element == null) {\n", - " console.error(\"Bokeh: ERROR: autoload.js configured with elementid '1001' but no matching script tag was found. \")\n", - " return false;\n", - " }\n", - "\n", - " function inject_raw_css(css) {\n", - " const element = document.createElement(\"style\");\n", - " element.appendChild(document.createTextNode(css));\n", - " document.body.appendChild(element);\n", - " }\n", - "\n", - " var js_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-1.2.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.2.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.2.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-gl-1.2.0.min.js\"];\n", - " var css_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-1.2.0.min.css\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.2.0.min.css\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.2.0.min.css\"];\n", - "\n", - " var inline_js = [\n", - " function(Bokeh) {\n", - " Bokeh.set_log_level(\"info\");\n", - " },\n", - " \n", - " function(Bokeh) {\n", - " \n", - " },\n", - " function(Bokeh) {} // ensure no trailing comma for IE\n", - " ];\n", - "\n", - " function run_inline_js() {\n", - " \n", - " if ((root.Bokeh !== undefined) || (force === true)) {\n", - " for (var i = 0; i < inline_js.length; i++) {\n", - " inline_js[i].call(root, root.Bokeh);\n", - " }if (force === true) {\n", - " display_loaded();\n", - " }} else if (Date.now() < root._bokeh_timeout) {\n", - " setTimeout(run_inline_js, 100);\n", - " } else if (!root._bokeh_failed_load) {\n", - " console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n", - " root._bokeh_failed_load = true;\n", - " } else if (force !== true) {\n", - " var cell = $(document.getElementById(\"1001\")).parents('.cell').data().cell;\n", - " cell.output_area.append_execute_result(NB_LOAD_WARNING)\n", - " }\n", - "\n", - " }\n", - "\n", - " if (root._bokeh_is_loading === 0) {\n", - " console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n", - " run_inline_js();\n", - " } else {\n", - " load_libs(css_urls, js_urls, function() {\n", - " console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n", - " run_inline_js();\n", - " });\n", - " }\n", - "}(window));" - ], - "application/vnd.bokehjs_load.v0+json": "\n(function(root) {\n function now() {\n return new Date();\n }\n\n var force = true;\n\n if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\n \n\n \n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n var NB_LOAD_WARNING = {'data': {'text/html':\n \"
\\n\"+\n \"

\\n\"+\n \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n \"

\\n\"+\n \"
    \\n\"+\n \"
  • re-rerun `output_notebook()` to attempt to load from CDN again, or
  • \\n\"+\n \"
  • use INLINE resources instead, as so:
  • \\n\"+\n \"
\\n\"+\n \"\\n\"+\n \"from bokeh.resources import INLINE\\n\"+\n \"output_notebook(resources=INLINE)\\n\"+\n \"\\n\"+\n \"
\"}};\n\n function display_loaded() {\n var el = document.getElementById(\"1001\");\n if (el != null) {\n el.textContent = \"BokehJS is loading...\";\n }\n if (root.Bokeh !== undefined) {\n if (el != null) {\n el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n }\n } else if (Date.now() < root._bokeh_timeout) {\n setTimeout(display_loaded, 100)\n }\n }\n\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls == null || js_urls.length === 0) {\n run_callbacks();\n return null;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n root._bokeh_is_loading = css_urls.length + js_urls.length;\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error() {\n console.error(\"failed to load \" + url);\n }\n\n for (var i = 0; i < css_urls.length; i++) {\n var url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error;\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n for (var i = 0; i < js_urls.length; i++) {\n var url = js_urls[i];\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n };var element = document.getElementById(\"1001\");\n if (element == null) {\n console.error(\"Bokeh: ERROR: autoload.js configured with elementid '1001' but no matching script tag was found. \")\n return false;\n }\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n var js_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-1.2.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.2.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.2.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-gl-1.2.0.min.js\"];\n var css_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-1.2.0.min.css\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.2.0.min.css\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.2.0.min.css\"];\n\n var inline_js = [\n function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\n \n function(Bokeh) {\n \n },\n function(Bokeh) {} // ensure no trailing comma for IE\n ];\n\n function run_inline_js() {\n \n if ((root.Bokeh !== undefined) || (force === true)) {\n for (var i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }if (force === true) {\n display_loaded();\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n } else if (force !== true) {\n var cell = $(document.getElementById(\"1001\")).parents('.cell').data().cell;\n cell.output_area.append_execute_result(NB_LOAD_WARNING)\n }\n\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));" - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "import bokeh\n", - "import bokeh.plotting as bp\n", - "bp.output_notebook()\n", - "\n", - "import datetime\n", - "import socket\n", - "def get_compact_timestamp():\n", - " now = datetime.datetime.now()\n", - " return now.strftime(\"%Y%m%d.%H%M%S\")\n", - "\n", - "def _save_figure_to_bucket(fig, name, title=None, export_format=\"html\"):\n", - " now = get_compact_timestamp()\n", - " fname = f\"{name}.{now:s}.{export_format}\"\n", - " title = title or name\n", - " if fname.endswith('.png'):\n", - " bokeh.io.export_png(p, os.path.join(\"/tmp\", fname))\n", - " else:\n", - " bp.save(p, os.path.join(\"/tmp\", fname), title=title, \n", - " resources=bokeh.resources.CDN)\n", - " hostname = socket.gethostname()\n", - " GCP_PROJECT=\"edge-probing\"\n", - " !gsutil cp /tmp/$fname gs://$GCP_PROJECT/$hostname/plots/$fname\n", - " !gsutil acl ch -u AllUsers:R gs://$GCP_PROJECT/$hostname/plots/$fname\n", - " url = f\"https://storage.googleapis.com/{GCP_PROJECT}/{hostname}/plots/{fname}\"\n", - " print(f\"Public URL: {url}\")\n", - " return url" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": { - "nbpresent": { - "id": "e51ba443-98b7-41bb-8e01-9126d3b77c2e" - } - }, - "outputs": [], - "source": [ - "ID_COLS = ['run', 'task', 'split']\n", - "\n", - "def agg_label_group(df, task_predicate, label_predicate, group_name):\n", - " agg_map = {k:\"sum\" for k in df.columns if k.endswith(\"_count\")}\n", - " mask = df['task'].map(task_predicate) & df['label'].map(label_predicate)\n", - " sdf = df[mask].groupby(by=ID_COLS).agg(agg_map).reset_index()\n", - " sdf['label'] = group_name\n", - " return sdf\n", - "\n", - "def agg_stratifier_group(df, stratifier, key_predicate, group_name):\n", - " agg_map = {k:\"sum\" for k in df.columns if k.endswith(\"_count\")}\n", - " # Use this for short-circuit evaluation, so we don't call key_predicate on invalid keys\n", - " mask = [(s == stratifier and key_predicate(key)) \n", - " for s, key in zip(df['stratifier'], df['stratum_key'])]\n", - " sdf = df[mask].groupby(by=ID_COLS).agg(agg_map).reset_index()\n", - " sdf['label'] = group_name\n", - " return sdf \n", - "\n", - "def load_scores_file(filename, tag=None, seed=None):\n", - " df = pd.read_csv(filename, sep=\"\\t\", header=0)\n", - " df.drop(['Unnamed: 0'], axis='columns', inplace=True)\n", - " # df['task_raw'] = df['task'].copy()\n", - " df['task'] = df['task'].map(analysis.clean_task_name)\n", - " if not \"stratifier\" in df.columns:\n", - " df[\"stratifier\"] = None\n", - " if not \"stratum_key\" in df.columns:\n", - " df[\"stratum_key\"] = 0\n", - " \n", - " ###\n", - " # Add additional custom aggregations\n", - " _eg = []\n", - " # SRL core, non-core, and cleaned micro F1\n", - " _eg.append(agg_label_group(df, analysis.is_srl_task, analysis.is_core_role, \"_core_\"))\n", - " _eg.append(agg_label_group(df, analysis.is_srl_task, analysis.is_non_core_role, \"_non_core_\"))\n", - " _eg.append(agg_label_group(df, analysis.is_srl_task, analysis.is_core_or_noncore, \"_clean_micro_\"))\n", - " # Constituents: split into POS, nonterminals\n", - " _eg.append(agg_stratifier_group(df, 'info.height', lambda x: int(x) == 1, \"_pos_\"))\n", - " _eg.append(agg_stratifier_group(df, 'info.height', lambda x: int(x) > 1, \"_nonterminal_\"))\n", - " # Relations: ignore negative class (no_relation)\n", - " _eg.append(agg_label_group(df, analysis.is_relation_task, analysis.is_positive_relation, \"_clean_micro_\"))\n", - " df = pd.concat([df] + _eg, ignore_index=True, sort=False)\n", - " \n", - " df.insert(0, \"exp_name\", df['run'].map(lambda p: os.path.basename(os.path.dirname(p.strip(\"/\")))))\n", - " df.insert(1, \"exp_type\", df['exp_name'].map(analysis.get_exp_type))\n", - " df.insert(1, \"layer_num\", df['exp_name'].map(analysis.get_layer_num))\n", - " if tag is not None:\n", - " df.insert(0, \"tag\", tag)\n", - " df.insert(1, \"seed\", seed)\n", - " return df" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "nbpresent": { - "id": "a5dbfdad-dd87-4c19-9507-1231e5251cb2" - } - }, - "source": [ - "## Specify score files and load" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": { - "nbpresent": { - "id": "3de2e9a1-4976-42ab-b927-5a9081f01054" - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "['rel-semeval' 'coref-ontonotes']\n", - "['bert-base-uncased-mix']\n" - ] - } - ], - "source": [ - "score_files = []\n", - "# Add (tag, path/to/scores.tsv) tuples here; results will be concatenated.\n", - "score_files = [\n", - "# (\"base\", \"/nfs/jiant/exp/iftenney/20190721-test-ep-bert/stats.tsv\"),\n", - "# (\"base\", \"/nfs/jiant/exp/iftenney/20190721-test-ep-bert-medium/stats.tsv\"),\n", - " (\"base\", \"/nfs/jiant/exp/iftenney/20190721-bert-base-layers/scores.tsv\"),\n", - "]\n", - "dfs = []\n", - "for tag, score_file in score_files:\n", - " df = load_scores_file(score_file, tag=tag)\n", - " dfs.append(df)\n", - "\n", - "df = pd.concat(dfs, ignore_index=True, sort=False)\n", - "def _format_display_col(exp_type, layer_num, tag):\n", - " ret = exp_type\n", - " if layer_num:\n", - " ret += f\"-{layer_num}\"\n", - " if tag:\n", - " ret += f\" ({tag})\"\n", - " return ret\n", - "\n", - "df['display_col'] = list(map(_format_display_col, df.exp_type, df.layer_num, df.tag))\n", - "print(df['task'].unique())\n", - "print(df['exp_type'].unique())" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": { - "nbpresent": { - "id": "975c73b5-a1e4-4ff8-933f-a97fe7de3220" - } - }, - "outputs": [], - "source": [ - "analysis.score_from_confusion_matrix(df)\n", - "\n", - "def _get_final_score(row):\n", - " return row['f1_score'], row['f1_errn95']\n", - "\n", - "df['score'], df['score_errn95'] = zip(*(_get_final_score(row) for i, row in df.iterrows()))" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": { - "nbpresent": { - "id": "6c374262-2146-420c-9592-4d92dbb92889" - } - }, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
tagseedexp_namelayer_numexp_typeruntasksplitlabelfn_count...accuracyprecisionrecallf1_scoreaccuracy_errn95precision_errn95recall_errn95f1_errn95scorescore_errn95
0baseNonebert-base-uncased-mix_00-edges-rel-semeval00bert-base-uncased-mix/nfs/jiant/exp/iftenney/20190721-bert-base-lay...rel-semevalvalCause-Effect(e1,e2)32...0.9617060.5714290.3333330.4210530.0110960.1833030.1333610.1543940.4210530.154394
1baseNonebert-base-uncased-mix_00-edges-rel-semeval00bert-base-uncased-mix/nfs/jiant/exp/iftenney/20190721-bert-base-lay...rel-semevalvalCause-Effect(e2,e1)40...0.9503920.7763160.5959600.6742860.0125550.0936880.0966630.0951520.6742860.095152
2baseNonebert-base-uncased-mix_00-edges-rel-semeval00bert-base-uncased-mix/nfs/jiant/exp/iftenney/20190721-bert-base-lay...rel-semevalvalComponent-Whole(e1,e2)32...0.9643170.8085110.5428570.6495730.0107260.1124920.1167010.1145580.6495730.114558
3baseNonebert-base-uncased-mix_00-edges-rel-semeval00bert-base-uncased-mix/nfs/jiant/exp/iftenney/20190721-bert-base-lay...rel-semevalvalComponent-Whole(e2,e1)37...0.9564840.7173910.4714290.5689660.0117970.1301210.1169410.1231800.5689660.123180
4baseNonebert-base-uncased-mix_00-edges-rel-semeval00bert-base-uncased-mix/nfs/jiant/exp/iftenney/20190721-bert-base-lay...rel-semevalvalContent-Container(e1,e2)12...0.9817230.7567570.7000000.7272730.0077450.1382460.1420150.1401060.7272730.140106
\n", - "

5 rows × 29 columns

\n", - "
" - ], - "text/plain": [ - " tag seed exp_name layer_num \\\n", - "0 base None bert-base-uncased-mix_00-edges-rel-semeval 00 \n", - "1 base None bert-base-uncased-mix_00-edges-rel-semeval 00 \n", - "2 base None bert-base-uncased-mix_00-edges-rel-semeval 00 \n", - "3 base None bert-base-uncased-mix_00-edges-rel-semeval 00 \n", - "4 base None bert-base-uncased-mix_00-edges-rel-semeval 00 \n", - "\n", - " exp_type run \\\n", - "0 bert-base-uncased-mix /nfs/jiant/exp/iftenney/20190721-bert-base-lay... \n", - "1 bert-base-uncased-mix /nfs/jiant/exp/iftenney/20190721-bert-base-lay... \n", - "2 bert-base-uncased-mix /nfs/jiant/exp/iftenney/20190721-bert-base-lay... \n", - "3 bert-base-uncased-mix /nfs/jiant/exp/iftenney/20190721-bert-base-lay... \n", - "4 bert-base-uncased-mix /nfs/jiant/exp/iftenney/20190721-bert-base-lay... \n", - "\n", - " task split label fn_count ... \\\n", - "0 rel-semeval val Cause-Effect(e1,e2) 32 ... \n", - "1 rel-semeval val Cause-Effect(e2,e1) 40 ... \n", - "2 rel-semeval val Component-Whole(e1,e2) 32 ... \n", - "3 rel-semeval val Component-Whole(e2,e1) 37 ... \n", - "4 rel-semeval val Content-Container(e1,e2) 12 ... \n", - "\n", - " accuracy precision recall f1_score accuracy_errn95 precision_errn95 \\\n", - "0 0.961706 0.571429 0.333333 0.421053 0.011096 0.183303 \n", - "1 0.950392 0.776316 0.595960 0.674286 0.012555 0.093688 \n", - "2 0.964317 0.808511 0.542857 0.649573 0.010726 0.112492 \n", - "3 0.956484 0.717391 0.471429 0.568966 0.011797 0.130121 \n", - "4 0.981723 0.756757 0.700000 0.727273 0.007745 0.138246 \n", - "\n", - " recall_errn95 f1_errn95 score score_errn95 \n", - "0 0.133361 0.154394 0.421053 0.154394 \n", - "1 0.096663 0.095152 0.674286 0.095152 \n", - "2 0.116701 0.114558 0.649573 0.114558 \n", - "3 0.116941 0.123180 0.568966 0.123180 \n", - "4 0.142015 0.140106 0.727273 0.140106 \n", - "\n", - "[5 rows x 29 columns]" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "df.head()" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "nbpresent": { - "id": "da90cd74-743a-4995-8144-e561826d6206" - } - }, - "source": [ - "For DPR, we need to average across multiple runs to get a good estimate of performance." - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": { - "nbpresent": { - "id": "7193ffc4-31d2-42d3-b198-39ce7dfd2b5e" - } - }, - "outputs": [], - "source": [ - "mask = df['task'] == 'dpr'\n", - "mask &= df['label'] != \"__run_info__\"\n", - "mask &= df['seed'].notnull()\n", - "gb_cols = [\"tag\", \"exp_name\", \"exp_type\", \"task\", \"label\", \"split\", \"display_col\"]\n", - "gb = df[mask].groupby(by=gb_cols)\n", - "new_rows = []\n", - "for key, idxs in gb.groups.items():\n", - " new_row = dict(zip(gb_cols, key))\n", - " new_row[\"seed\"] = \"_mean_\"\n", - " new_row[\"score\"] = df.loc[idxs, \"score\"].mean()\n", - " new_row[\"score_errn95\"] = 1.96 * np.sqrt(df.loc[idxs, \"score\"].var()/len(idxs))\n", - " new_rows.append(new_row)\n", - " \n", - "agg_df = pd.DataFrame.from_records(new_rows)\n", - "df = pd.concat([df, agg_df], ignore_index=True, sort=False)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "nbpresent": { - "id": "8ae1f12b-87dc-41f6-9351-7ee325abb10e" - } - }, - "source": [ - "For SemEval 2010 Task 8, the official metric is macro-averaged F1 over non-Other labels. Compute this so we can compare to SOTA." - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": { - "nbpresent": { - "id": "371b0ce3-4892-4052-aaf1-118a25897307" - }, - "scrolled": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "run,split,score\n", - "/nfs/jiant/exp/iftenney/20190721-bert-base-layers//bert-base-uncased-mix_00-edges-rel-semeval/run,test,0.5293\n", - "/nfs/jiant/exp/iftenney/20190721-bert-base-layers//bert-base-uncased-mix_00-edges-rel-semeval/run,val,0.5096\n", - "/nfs/jiant/exp/iftenney/20190721-bert-base-layers//bert-base-uncased-mix_01-edges-rel-semeval/run,test,0.5858\n", - "/nfs/jiant/exp/iftenney/20190721-bert-base-layers//bert-base-uncased-mix_01-edges-rel-semeval/run,val,0.5713\n", - "/nfs/jiant/exp/iftenney/20190721-bert-base-layers//bert-base-uncased-mix_02-edges-rel-semeval/run,test,0.6075\n", - "/nfs/jiant/exp/iftenney/20190721-bert-base-layers//bert-base-uncased-mix_02-edges-rel-semeval/run,val,0.5922\n", - "/nfs/jiant/exp/iftenney/20190721-bert-base-layers//bert-base-uncased-mix_03-edges-rel-semeval/run,test,0.6082\n", - "/nfs/jiant/exp/iftenney/20190721-bert-base-layers//bert-base-uncased-mix_03-edges-rel-semeval/run,val,0.6006\n", - "/nfs/jiant/exp/iftenney/20190721-bert-base-layers//bert-base-uncased-mix_04-edges-rel-semeval/run,test,0.6655\n", - "/nfs/jiant/exp/iftenney/20190721-bert-base-layers//bert-base-uncased-mix_04-edges-rel-semeval/run,val,0.6420\n", - "/nfs/jiant/exp/iftenney/20190721-bert-base-layers//bert-base-uncased-mix_05-edges-rel-semeval/run,test,0.6826\n", - "/nfs/jiant/exp/iftenney/20190721-bert-base-layers//bert-base-uncased-mix_05-edges-rel-semeval/run,val,0.6725\n", - "/nfs/jiant/exp/iftenney/20190721-bert-base-layers//bert-base-uncased-mix_06-edges-rel-semeval/run,test,0.6752\n", - "/nfs/jiant/exp/iftenney/20190721-bert-base-layers//bert-base-uncased-mix_06-edges-rel-semeval/run,val,0.6608\n", - "/nfs/jiant/exp/iftenney/20190721-bert-base-layers//bert-base-uncased-mix_07-edges-rel-semeval/run,test,0.7071\n", - "/nfs/jiant/exp/iftenney/20190721-bert-base-layers//bert-base-uncased-mix_07-edges-rel-semeval/run,val,0.7076\n", - "/nfs/jiant/exp/iftenney/20190721-bert-base-layers//bert-base-uncased-mix_08-edges-rel-semeval/run,test,0.7260\n", - "/nfs/jiant/exp/iftenney/20190721-bert-base-layers//bert-base-uncased-mix_08-edges-rel-semeval/run,val,0.7334\n", - "/nfs/jiant/exp/iftenney/20190721-bert-base-layers//bert-base-uncased-mix_09-edges-rel-semeval/run,test,0.7313\n", - "/nfs/jiant/exp/iftenney/20190721-bert-base-layers//bert-base-uncased-mix_09-edges-rel-semeval/run,val,0.7260\n", - "/nfs/jiant/exp/iftenney/20190721-bert-base-layers//bert-base-uncased-mix_10-edges-rel-semeval/run,test,0.7344\n", - "/nfs/jiant/exp/iftenney/20190721-bert-base-layers//bert-base-uncased-mix_10-edges-rel-semeval/run,val,0.7381\n", - "/nfs/jiant/exp/iftenney/20190721-bert-base-layers//bert-base-uncased-mix_11-edges-rel-semeval/run,test,0.7406\n", - "/nfs/jiant/exp/iftenney/20190721-bert-base-layers//bert-base-uncased-mix_11-edges-rel-semeval/run,val,0.7458\n", - "/nfs/jiant/exp/iftenney/20190721-bert-base-layers//bert-base-uncased-mix_12-edges-rel-semeval/run,test,0.7375\n", - "/nfs/jiant/exp/iftenney/20190721-bert-base-layers//bert-base-uncased-mix_12-edges-rel-semeval/run,val,0.7431\n", - "\n" - ] - } - ], - "source": [ - "mask = df['task'] == 'rel-semeval'\n", - "mask &= df['split'].notnull()\n", - "mask &= df['label'].map(analysis.is_positive_relation)\n", - "_id_cols = ['run', 'split']\n", - "_agg_cols = ['score']\n", - "gb = df[mask][_id_cols + _agg_cols].groupby(_id_cols)\n", - "afd = gb.agg('mean')\n", - "afd = afd.reset_index()\n", - "\n", - "csv_args = dict(float_format=\"%.4f\")\n", - "print(afd.to_csv(index=False, **csv_args))" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "nbpresent": { - "id": "6a0daefb-44bf-4062-94ec-fba2bc96d001" - } - }, - "source": [ - "## Compute clean metrics for each task\n", - "\n", - "For most tasks this is just the micro or macro average F1, but we need to ignore the 0 label for coref, and drop references and continuations for SRL." - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": { - "nbpresent": { - "id": "57b4606b-ac23-48ed-85aa-4b33b4075f12" - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "26\n" - ] - }, - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
tagseedexp_namelayer_numexp_typeruntasksplitlabelfn_count...precisionrecallf1_scoreaccuracy_errn95precision_errn95recall_errn95f1_errn95scorescore_errn95display_row
0baseNonebert-base-uncased-mix_00-edges-rel-semeval00bert-base-uncased-mix/nfs/jiant/exp/iftenney/20190721-bert-base-lay...rel-semevaltest_clean_micro_1152...0.7218970.4909410.5844290.0015670.0223860.0205970.0214550.5844290.021455rel-semeval-_clean_micro_
1baseNonebert-base-uncased-mix_01-edges-rel-semeval01bert-base-uncased-mix/nfs/jiant/exp/iftenney/20190721-bert-base-lay...rel-semevaltest_clean_micro_987...0.7554770.5638530.6457490.0014780.0204980.0204320.0204650.6457490.020465rel-semeval-_clean_micro_
2baseNonebert-base-uncased-mix_02-edges-rel-semeval02bert-base-uncased-mix/nfs/jiant/exp/iftenney/20190721-bert-base-lay...rel-semevaltest_clean_micro_933...0.7860520.5877150.6725660.0014230.0195400.0202810.0199040.6725660.019904rel-semeval-_clean_micro_
3baseNonebert-base-uncased-mix_03-edges-rel-semeval03bert-base-uncased-mix/nfs/jiant/exp/iftenney/20190721-bert-base-lay...rel-semevaltest_clean_micro_880...0.7994220.6111360.6927120.0013860.0188700.0200850.0194590.6927120.019459rel-semeval-_clean_micro_
4baseNonebert-base-uncased-mix_04-edges-rel-semeval04bert-base-uncased-mix/nfs/jiant/exp/iftenney/20190721-bert-base-lay...rel-semevaltest_clean_micro_747...0.7953830.6699070.7272730.0013360.0181110.0193750.0187220.7272730.018722rel-semeval-_clean_micro_
5baseNonebert-base-uncased-mix_05-edges-rel-semeval05bert-base-uncased-mix/nfs/jiant/exp/iftenney/20190721-bert-base-lay...rel-semevaltest_clean_micro_674...0.8132040.7021650.7536160.0012780.0172810.0188420.0180280.7536160.018028rel-semeval-_clean_micro_
6baseNonebert-base-uncased-mix_06-edges-rel-semeval06bert-base-uncased-mix/nfs/jiant/exp/iftenney/20190721-bert-base-lay...rel-semevaltest_clean_micro_693...0.8250130.6937690.7537210.0012700.0170710.0189910.0179800.7537210.017980rel-semeval-_clean_micro_
7baseNonebert-base-uncased-mix_07-edges-rel-semeval07bert-base-uncased-mix/nfs/jiant/exp/iftenney/20190721-bert-base-lay...rel-semevaltest_clean_micro_626...0.8339280.7233760.7747280.0012240.0164630.0184310.0173910.7747280.017391rel-semeval-_clean_micro_
8baseNonebert-base-uncased-mix_08-edges-rel-semeval08bert-base-uncased-mix/nfs/jiant/exp/iftenney/20190721-bert-base-lay...rel-semevaltest_clean_micro_548...0.8419240.7578440.7976740.0011720.0158430.0176500.0166980.7976740.016698rel-semeval-_clean_micro_
9baseNonebert-base-uncased-mix_09-edges-rel-semeval09bert-base-uncased-mix/nfs/jiant/exp/iftenney/20190721-bert-base-lay...rel-semevaltest_clean_micro_541...0.8554400.7609370.8054260.0011460.0153620.0175730.0163930.8054260.016393rel-semeval-_clean_micro_
10baseNonebert-base-uncased-mix_10-edges-rel-semeval10bert-base-uncased-mix/nfs/jiant/exp/iftenney/20190721-bert-base-lay...rel-semevaltest_clean_micro_502...0.8519590.7781710.8133950.0011300.0153100.0171180.0161640.8133950.016164rel-semeval-_clean_micro_
11baseNonebert-base-uncased-mix_11-edges-rel-semeval11bert-base-uncased-mix/nfs/jiant/exp/iftenney/20190721-bert-base-lay...rel-semevaltest_clean_micro_505...0.8604990.7768450.8165350.0011170.0150240.0171550.0160190.8165350.016019rel-semeval-_clean_micro_
12baseNonebert-base-uncased-mix_12-edges-rel-semeval12bert-base-uncased-mix/nfs/jiant/exp/iftenney/20190721-bert-base-lay...rel-semevaltest_clean_micro_512...0.8595970.7737520.8144190.0011230.0150870.0172390.0160910.8144190.016091rel-semeval-_clean_micro_
13baseNonebert-base-uncased-mix_00-edges-coref-ontonotes00bert-base-uncased-mix/nfs/jiant/exp/iftenney/20190721-bert-base-lay...coref-ontonotestest11496...0.7635750.7516600.7575710.0035920.0108140.0109110.0108620.7575710.010862coref-ontonotes-1
14baseNonebert-base-uncased-mix_01-edges-coref-ontonotes01bert-base-uncased-mix/nfs/jiant/exp/iftenney/20190721-bert-base-lay...coref-ontonotestest11068...0.8302900.8227090.8264820.0030940.0095230.0096450.0095830.8264820.009583coref-ontonotes-1
15baseNonebert-base-uncased-mix_02-edges-coref-ontonotes02bert-base-uncased-mix/nfs/jiant/exp/iftenney/20190721-bert-base-lay...coref-ontonotestest1888...0.8352580.8525900.8438350.0029670.0092720.0089530.0091090.8438350.009109coref-ontonotes-1
16baseNonebert-base-uncased-mix_03-edges-coref-ontonotes03bert-base-uncased-mix/nfs/jiant/exp/iftenney/20190721-bert-base-lay...coref-ontonotestest1787...0.8410150.8693560.8549510.0028750.0090820.0085110.0087870.8549510.008787coref-ontonotes-1
17baseNonebert-base-uncased-mix_04-edges-coref-ontonotes04bert-base-uncased-mix/nfs/jiant/exp/iftenney/20190721-bert-base-lay...coref-ontonotestest1707...0.8511290.8826360.8665960.0027670.0088270.0081280.0084630.8665960.008463coref-ontonotes-1
18baseNonebert-base-uncased-mix_05-edges-coref-ontonotes05bert-base-uncased-mix/nfs/jiant/exp/iftenney/20190721-bert-base-lay...coref-ontonotestest1699...0.8682540.8839640.8760380.0026620.0084650.0080880.0082720.8760380.008272coref-ontonotes-1
19baseNonebert-base-uncased-mix_06-edges-coref-ontonotes06bert-base-uncased-mix/nfs/jiant/exp/iftenney/20190721-bert-base-lay...coref-ontonotestest1673...0.8802430.8882800.8842440.0025720.0081620.0079550.0080570.8842440.008057coref-ontonotes-1
20baseNonebert-base-uncased-mix_07-edges-coref-ontonotes07bert-base-uncased-mix/nfs/jiant/exp/iftenney/20190721-bert-base-lay...coref-ontonotestest1619...0.8883960.8972440.8927980.0024800.0079120.0076680.0077880.8927980.007788coref-ontonotes-1
21baseNonebert-base-uncased-mix_08-edges-coref-ontonotes08bert-base-uncased-mix/nfs/jiant/exp/iftenney/20190721-bert-base-lay...coref-ontonotestest1548...0.8885280.9090310.8986630.0024220.0078570.0072620.0075480.8986630.007548coref-ontonotes-1
22baseNonebert-base-uncased-mix_09-edges-coref-ontonotes09bert-base-uncased-mix/nfs/jiant/exp/iftenney/20190721-bert-base-lay...coref-ontonotestest1571...0.8977610.9052120.9014710.0023810.0076190.0073970.0075070.9014710.007507coref-ontonotes-1
23baseNonebert-base-uncased-mix_10-edges-coref-ontonotes10bert-base-uncased-mix/nfs/jiant/exp/iftenney/20190721-bert-base-lay...coref-ontonotestest1530...0.8980060.9120190.9049580.0023450.0075840.0071530.0073620.9049580.007362coref-ontonotes-1
24baseNonebert-base-uncased-mix_11-edges-coref-ontonotes11bert-base-uncased-mix/nfs/jiant/exp/iftenney/20190721-bert-base-lay...coref-ontonotestest1507...0.8925740.9158370.9040560.0023610.0077200.0070110.0073480.9040560.007348coref-ontonotes-1
25baseNonebert-base-uncased-mix_12-edges-coref-ontonotes12bert-base-uncased-mix/nfs/jiant/exp/iftenney/20190721-bert-base-lay...coref-ontonotestest1589...0.9020750.9022240.9021500.0023690.0075050.0075000.0075030.9021500.007503coref-ontonotes-1
\n", - "

26 rows × 30 columns

\n", - "
" - ], - "text/plain": [ - " tag seed exp_name layer_num \\\n", - "0 base None bert-base-uncased-mix_00-edges-rel-semeval 00 \n", - "1 base None bert-base-uncased-mix_01-edges-rel-semeval 01 \n", - "2 base None bert-base-uncased-mix_02-edges-rel-semeval 02 \n", - "3 base None bert-base-uncased-mix_03-edges-rel-semeval 03 \n", - "4 base None bert-base-uncased-mix_04-edges-rel-semeval 04 \n", - "5 base None bert-base-uncased-mix_05-edges-rel-semeval 05 \n", - "6 base None bert-base-uncased-mix_06-edges-rel-semeval 06 \n", - "7 base None bert-base-uncased-mix_07-edges-rel-semeval 07 \n", - "8 base None bert-base-uncased-mix_08-edges-rel-semeval 08 \n", - "9 base None bert-base-uncased-mix_09-edges-rel-semeval 09 \n", - "10 base None bert-base-uncased-mix_10-edges-rel-semeval 10 \n", - "11 base None bert-base-uncased-mix_11-edges-rel-semeval 11 \n", - "12 base None bert-base-uncased-mix_12-edges-rel-semeval 12 \n", - "13 base None bert-base-uncased-mix_00-edges-coref-ontonotes 00 \n", - "14 base None bert-base-uncased-mix_01-edges-coref-ontonotes 01 \n", - "15 base None bert-base-uncased-mix_02-edges-coref-ontonotes 02 \n", - "16 base None bert-base-uncased-mix_03-edges-coref-ontonotes 03 \n", - "17 base None bert-base-uncased-mix_04-edges-coref-ontonotes 04 \n", - "18 base None bert-base-uncased-mix_05-edges-coref-ontonotes 05 \n", - "19 base None bert-base-uncased-mix_06-edges-coref-ontonotes 06 \n", - "20 base None bert-base-uncased-mix_07-edges-coref-ontonotes 07 \n", - "21 base None bert-base-uncased-mix_08-edges-coref-ontonotes 08 \n", - "22 base None bert-base-uncased-mix_09-edges-coref-ontonotes 09 \n", - "23 base None bert-base-uncased-mix_10-edges-coref-ontonotes 10 \n", - "24 base None bert-base-uncased-mix_11-edges-coref-ontonotes 11 \n", - "25 base None bert-base-uncased-mix_12-edges-coref-ontonotes 12 \n", - "\n", - " exp_type run \\\n", - "0 bert-base-uncased-mix /nfs/jiant/exp/iftenney/20190721-bert-base-lay... \n", - "1 bert-base-uncased-mix /nfs/jiant/exp/iftenney/20190721-bert-base-lay... \n", - "2 bert-base-uncased-mix /nfs/jiant/exp/iftenney/20190721-bert-base-lay... \n", - "3 bert-base-uncased-mix /nfs/jiant/exp/iftenney/20190721-bert-base-lay... \n", - "4 bert-base-uncased-mix /nfs/jiant/exp/iftenney/20190721-bert-base-lay... \n", - "5 bert-base-uncased-mix /nfs/jiant/exp/iftenney/20190721-bert-base-lay... \n", - "6 bert-base-uncased-mix /nfs/jiant/exp/iftenney/20190721-bert-base-lay... \n", - "7 bert-base-uncased-mix /nfs/jiant/exp/iftenney/20190721-bert-base-lay... \n", - "8 bert-base-uncased-mix /nfs/jiant/exp/iftenney/20190721-bert-base-lay... \n", - "9 bert-base-uncased-mix /nfs/jiant/exp/iftenney/20190721-bert-base-lay... \n", - "10 bert-base-uncased-mix /nfs/jiant/exp/iftenney/20190721-bert-base-lay... \n", - "11 bert-base-uncased-mix /nfs/jiant/exp/iftenney/20190721-bert-base-lay... \n", - "12 bert-base-uncased-mix /nfs/jiant/exp/iftenney/20190721-bert-base-lay... \n", - "13 bert-base-uncased-mix /nfs/jiant/exp/iftenney/20190721-bert-base-lay... \n", - "14 bert-base-uncased-mix /nfs/jiant/exp/iftenney/20190721-bert-base-lay... \n", - "15 bert-base-uncased-mix /nfs/jiant/exp/iftenney/20190721-bert-base-lay... \n", - "16 bert-base-uncased-mix /nfs/jiant/exp/iftenney/20190721-bert-base-lay... \n", - "17 bert-base-uncased-mix /nfs/jiant/exp/iftenney/20190721-bert-base-lay... \n", - "18 bert-base-uncased-mix /nfs/jiant/exp/iftenney/20190721-bert-base-lay... \n", - "19 bert-base-uncased-mix /nfs/jiant/exp/iftenney/20190721-bert-base-lay... \n", - "20 bert-base-uncased-mix /nfs/jiant/exp/iftenney/20190721-bert-base-lay... \n", - "21 bert-base-uncased-mix /nfs/jiant/exp/iftenney/20190721-bert-base-lay... \n", - "22 bert-base-uncased-mix /nfs/jiant/exp/iftenney/20190721-bert-base-lay... \n", - "23 bert-base-uncased-mix /nfs/jiant/exp/iftenney/20190721-bert-base-lay... \n", - "24 bert-base-uncased-mix /nfs/jiant/exp/iftenney/20190721-bert-base-lay... \n", - "25 bert-base-uncased-mix /nfs/jiant/exp/iftenney/20190721-bert-base-lay... \n", - "\n", - " task split label fn_count ... \\\n", - "0 rel-semeval test _clean_micro_ 1152 ... \n", - "1 rel-semeval test _clean_micro_ 987 ... \n", - "2 rel-semeval test _clean_micro_ 933 ... \n", - "3 rel-semeval test _clean_micro_ 880 ... \n", - "4 rel-semeval test _clean_micro_ 747 ... \n", - "5 rel-semeval test _clean_micro_ 674 ... \n", - "6 rel-semeval test _clean_micro_ 693 ... \n", - "7 rel-semeval test _clean_micro_ 626 ... \n", - "8 rel-semeval test _clean_micro_ 548 ... \n", - "9 rel-semeval test _clean_micro_ 541 ... \n", - "10 rel-semeval test _clean_micro_ 502 ... \n", - "11 rel-semeval test _clean_micro_ 505 ... \n", - "12 rel-semeval test _clean_micro_ 512 ... \n", - "13 coref-ontonotes test 1 1496 ... \n", - "14 coref-ontonotes test 1 1068 ... \n", - "15 coref-ontonotes test 1 888 ... \n", - "16 coref-ontonotes test 1 787 ... \n", - "17 coref-ontonotes test 1 707 ... \n", - "18 coref-ontonotes test 1 699 ... \n", - "19 coref-ontonotes test 1 673 ... \n", - "20 coref-ontonotes test 1 619 ... \n", - "21 coref-ontonotes test 1 548 ... \n", - "22 coref-ontonotes test 1 571 ... \n", - "23 coref-ontonotes test 1 530 ... \n", - "24 coref-ontonotes test 1 507 ... \n", - "25 coref-ontonotes test 1 589 ... \n", - "\n", - " precision recall f1_score accuracy_errn95 precision_errn95 \\\n", - "0 0.721897 0.490941 0.584429 0.001567 0.022386 \n", - "1 0.755477 0.563853 0.645749 0.001478 0.020498 \n", - "2 0.786052 0.587715 0.672566 0.001423 0.019540 \n", - "3 0.799422 0.611136 0.692712 0.001386 0.018870 \n", - "4 0.795383 0.669907 0.727273 0.001336 0.018111 \n", - "5 0.813204 0.702165 0.753616 0.001278 0.017281 \n", - "6 0.825013 0.693769 0.753721 0.001270 0.017071 \n", - "7 0.833928 0.723376 0.774728 0.001224 0.016463 \n", - "8 0.841924 0.757844 0.797674 0.001172 0.015843 \n", - "9 0.855440 0.760937 0.805426 0.001146 0.015362 \n", - "10 0.851959 0.778171 0.813395 0.001130 0.015310 \n", - "11 0.860499 0.776845 0.816535 0.001117 0.015024 \n", - "12 0.859597 0.773752 0.814419 0.001123 0.015087 \n", - "13 0.763575 0.751660 0.757571 0.003592 0.010814 \n", - "14 0.830290 0.822709 0.826482 0.003094 0.009523 \n", - "15 0.835258 0.852590 0.843835 0.002967 0.009272 \n", - "16 0.841015 0.869356 0.854951 0.002875 0.009082 \n", - "17 0.851129 0.882636 0.866596 0.002767 0.008827 \n", - "18 0.868254 0.883964 0.876038 0.002662 0.008465 \n", - "19 0.880243 0.888280 0.884244 0.002572 0.008162 \n", - "20 0.888396 0.897244 0.892798 0.002480 0.007912 \n", - "21 0.888528 0.909031 0.898663 0.002422 0.007857 \n", - "22 0.897761 0.905212 0.901471 0.002381 0.007619 \n", - "23 0.898006 0.912019 0.904958 0.002345 0.007584 \n", - "24 0.892574 0.915837 0.904056 0.002361 0.007720 \n", - "25 0.902075 0.902224 0.902150 0.002369 0.007505 \n", - "\n", - " recall_errn95 f1_errn95 score score_errn95 display_row \n", - "0 0.020597 0.021455 0.584429 0.021455 rel-semeval-_clean_micro_ \n", - "1 0.020432 0.020465 0.645749 0.020465 rel-semeval-_clean_micro_ \n", - "2 0.020281 0.019904 0.672566 0.019904 rel-semeval-_clean_micro_ \n", - "3 0.020085 0.019459 0.692712 0.019459 rel-semeval-_clean_micro_ \n", - "4 0.019375 0.018722 0.727273 0.018722 rel-semeval-_clean_micro_ \n", - "5 0.018842 0.018028 0.753616 0.018028 rel-semeval-_clean_micro_ \n", - "6 0.018991 0.017980 0.753721 0.017980 rel-semeval-_clean_micro_ \n", - "7 0.018431 0.017391 0.774728 0.017391 rel-semeval-_clean_micro_ \n", - "8 0.017650 0.016698 0.797674 0.016698 rel-semeval-_clean_micro_ \n", - "9 0.017573 0.016393 0.805426 0.016393 rel-semeval-_clean_micro_ \n", - "10 0.017118 0.016164 0.813395 0.016164 rel-semeval-_clean_micro_ \n", - "11 0.017155 0.016019 0.816535 0.016019 rel-semeval-_clean_micro_ \n", - "12 0.017239 0.016091 0.814419 0.016091 rel-semeval-_clean_micro_ \n", - "13 0.010911 0.010862 0.757571 0.010862 coref-ontonotes-1 \n", - "14 0.009645 0.009583 0.826482 0.009583 coref-ontonotes-1 \n", - "15 0.008953 0.009109 0.843835 0.009109 coref-ontonotes-1 \n", - "16 0.008511 0.008787 0.854951 0.008787 coref-ontonotes-1 \n", - "17 0.008128 0.008463 0.866596 0.008463 coref-ontonotes-1 \n", - "18 0.008088 0.008272 0.876038 0.008272 coref-ontonotes-1 \n", - "19 0.007955 0.008057 0.884244 0.008057 coref-ontonotes-1 \n", - "20 0.007668 0.007788 0.892798 0.007788 coref-ontonotes-1 \n", - "21 0.007262 0.007548 0.898663 0.007548 coref-ontonotes-1 \n", - "22 0.007397 0.007507 0.901471 0.007507 coref-ontonotes-1 \n", - "23 0.007153 0.007362 0.904958 0.007362 coref-ontonotes-1 \n", - "24 0.007011 0.007348 0.904056 0.007348 coref-ontonotes-1 \n", - "25 0.007500 0.007503 0.902150 0.007503 coref-ontonotes-1 \n", - "\n", - "[26 rows x 30 columns]" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "SPLIT = \"test\"\n", - "# SPLIT = \"val\"\n", - "mask = df['split'] == SPLIT\n", - "\n", - "final_scores = []\n", - "for task in df['task'].unique():\n", - " task_scores = df[mask & (df['task'] == task)]\n", - " if analysis.is_coref_task(task):\n", - " final_scores.append(task_scores[task_scores['label'] == \"1\"])\n", - " # For GAP coref, have stratified by gender\n", - " if task.startswith(\"coref-gap\"):\n", - " final_scores.append(task_scores[task_scores['label'] == \"_info.pronoun_gender_MASCULINE_1_\"])\n", - " final_scores.append(task_scores[task_scores['label'] == \"_info.pronoun_gender_FEMININE_1_\"])\n", - " elif task == \"dpr\":\n", - " dpr_mask = task_scores['seed'] == \"_mean_\"\n", - " dpr_mask &= task_scores['label'] == \"_micro_avg_\"\n", - " final_scores.append(task_scores[dpr_mask])\n", - " elif analysis.is_srl_task(task):\n", - " final_scores.append(task_scores[task_scores['label'] == '_core_'])\n", - " final_scores.append(task_scores[task_scores['label'] == '_non_core_'])\n", - " # Use clean version, average only over core or noncore roles.\n", - " final_scores.append(task_scores[task_scores['label'] == '_clean_micro_'])\n", - " elif analysis.is_relation_task(task):\n", - " # Relation tasks include specific \"no_relation\" label\n", - " final_scores.append(task_scores[task_scores['label'] == '_clean_micro_'])\n", - " elif task == \"noun-verb\":\n", - " # Noun-verb reports accuracy on VERB class\n", - " final_scores.append(task_scores[task_scores['label'] == 'VERB'])\n", - " else:\n", - " final_scores.append(task_scores[task_scores['label'] == '_micro_avg_'])\n", - " \n", - "fdf = pd.concat(final_scores, axis=0, ignore_index=True, sort=False)\n", - "# fdf['task_and_metric'] = [\"%s-%s\" % tl for tl in zip(fdf.task, fdf.label)]\n", - "def format_display_row(task, label, seed):\n", - " ret = f\"{task}-{label}\"\n", - " if seed:\n", - " ret += f\":{seed}\"\n", - " return ret\n", - "\n", - "fdf['display_row'] = [format_display_row(*args) for args in zip(fdf.task, fdf.label, fdf.seed)]\n", - "print(len(fdf))\n", - "fdf" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "nbpresent": { - "id": "17221f4c-e3b1-4987-8824-643ab9accbd5" - } - }, - "source": [ - "Pivot DataFrame to present each task on a row, and each experiment on a column.\n", - "\n", - "This form is suitable to copy-paste into a spreadsheet." - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": { - "nbpresent": { - "id": "9b06c697-bb71-4231-bd7e-e9028f85ffa4" - }, - "scrolled": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "display_row,bert-base-uncased-mix-00 (base),bert-base-uncased-mix-01 (base),bert-base-uncased-mix-02 (base),bert-base-uncased-mix-03 (base),bert-base-uncased-mix-04 (base),bert-base-uncased-mix-05 (base),bert-base-uncased-mix-06 (base),bert-base-uncased-mix-07 (base),bert-base-uncased-mix-08 (base),bert-base-uncased-mix-09 (base),bert-base-uncased-mix-10 (base),bert-base-uncased-mix-11 (base),bert-base-uncased-mix-12 (base)\n", - "coref-ontonotes-1,75.7571,82.6482,84.3835,85.4951,86.6596,87.6038,88.4244,89.2798,89.8663,90.1471,90.4958,90.4056,90.2150\n", - "rel-semeval-_clean_micro_,58.4429,64.5749,67.2566,69.2712,72.7273,75.3616,75.3721,77.4728,79.7674,80.5426,81.3395,81.6535,81.4419\n", - "\n" - ] - } - ], - "source": [ - "# Pivot to wide-form for spreadsheet, and sort in (mostly) stable order.\n", - "sheet_df = fdf.pivot(index=\"display_row\", columns=\"display_col\", values=\"score\")\n", - "sheet_df = sheet_df.reindex(sorted(sheet_df.columns, \n", - " key=exp_type_sort_key), axis=1)\n", - "sheet_df = sheet_df.reindex(sorted(sheet_df.index,\n", - " key=task_sort_key), axis=0)\n", - "# sheet_df\n", - "print((100*sheet_df).to_csv(**csv_args))" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "nbpresent": { - "id": "7256b0b5-f94e-4452-a395-24d43d8cc742" - } - }, - "source": [ - "Print the same format, but show the 95% confidence intervals for each score." - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": { - "nbpresent": { - "id": "a9b7c866-7614-458b-a585-47f22802c81c" - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "display_row,bert-base-uncased-mix-00 (base),bert-base-uncased-mix-01 (base),bert-base-uncased-mix-02 (base),bert-base-uncased-mix-03 (base),bert-base-uncased-mix-04 (base),bert-base-uncased-mix-05 (base),bert-base-uncased-mix-06 (base),bert-base-uncased-mix-07 (base),bert-base-uncased-mix-08 (base),bert-base-uncased-mix-09 (base),bert-base-uncased-mix-10 (base),bert-base-uncased-mix-11 (base),bert-base-uncased-mix-12 (base)\n", - "coref-ontonotes-1,1.0862,0.9583,0.9109,0.8787,0.8463,0.8272,0.8057,0.7788,0.7548,0.7507,0.7362,0.7348,0.7503\n", - "rel-semeval-_clean_micro_,2.1455,2.0465,1.9904,1.9459,1.8722,1.8028,1.7980,1.7391,1.6698,1.6393,1.6164,1.6019,1.6091\n", - "\n" - ] - } - ], - "source": [ - "sheet_df = fdf.pivot(index=\"display_row\", columns=\"display_col\", values=\"score_errn95\")\n", - "sheet_df = sheet_df.reindex(sorted(sheet_df.columns, \n", - " key=exp_type_sort_key), axis=1)\n", - "sheet_df = sheet_df.reindex(sorted(sheet_df.index,\n", - " key=task_sort_key), axis=0)\n", - "# sheet_df\n", - "print((100*sheet_df).to_csv(**csv_args))" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "nbpresent": { - "id": "aab22d14-0ec5-4235-a9bf-a69c3e5d328e" - } - }, - "source": [ - "## Load scalar mixing weights" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": { - "nbpresent": { - "id": "45c7a519-9fdf-486d-a7f0-e551f2a36e11" - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "['coref-ontonotes' 'rel-semeval']\n", - "['bert-base-uncased-mix']\n", - "26\n", - "Scalar sets: ['sent_encoder._text_field_embedder.scalar_mix.']\n" - ] - } - ], - "source": [ - "scalar_files = [\n", - " (\"base\", \"/nfs/jiant/exp/iftenney/20190721-bert-base-layers/scalars.tsv\"),\n", - "]\n", - "\n", - "def load_scalars_file(filename, tag=None):\n", - " df = pd.read_csv(filename, sep=\"\\t\", header=0)\n", - " df.drop(['Unnamed: 0'], axis='columns', inplace=True)\n", - " \n", - " df.insert(0, \"exp_name\", df['run'].map(lambda p: os.path.basename(os.path.dirname(p.strip(\"/\")))))\n", - " df.insert(1, \"exp_type\", df['exp_name'].map(analysis.get_exp_type))\n", - " df.insert(2, \"task\", df['exp_name'].map(lambda name: analysis.clean_task_name(name.split(\"-edges-\")[1])))\n", - " if tag is not None:\n", - " df.insert(0, \"tag\", tag)\n", - " \n", - " return df\n", - "\n", - "dfs = []\n", - "for tag, scalar_file in scalar_files:\n", - " dfs.append(load_scalars_file(scalar_file, tag=tag))\n", - "scalar_df = pd.concat(dfs, ignore_index=True, sort=False)\n", - "scalar_df['display_col'] = [\"%s (%s)\" % et for et in zip(scalar_df.exp_type, scalar_df.tag)]\n", - "# ELMo models also have 'scalar_mix_0.', which is for pretraining and not used by edge probing.\n", - "mask = scalar_df['scalar_set'].map(lambda s: s.endswith(\"scalar_mix.\") or s.endswith(\"scalar_mix_1.\"))\n", - "scalar_df = scalar_df[mask].copy()\n", - "print(scalar_df['task'].unique())\n", - "print(scalar_df['exp_type'].unique())\n", - "print(len(scalar_df))\n", - "print(\"Scalar sets:\", scalar_df['scalar_set'].unique())" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/home/iftenney/.conda/envs/jiant/lib/python3.6/site-packages/ipykernel_launcher.py:42: RuntimeWarning: invalid value encountered in double_scalars\n" - ] - }, - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
tagexp_nameexp_typetaskcheckpointgammalabelrunscalar_parameters.0scalar_set...789101112weight_entropyweight_kl_unifweight_exp_layerweight_exp_layer_oneplus
0basebert-base-uncased-mix_00-edges-coref-ontonotesbert-base-uncased-mixcoref-ontonotes/edges-coref-ontonotes/model_state_target_trai...1.731095__scalar_mix__/nfs/jiant/exp/iftenney/20190721-bert-base-lay...0.000000sent_encoder._text_field_embedder.scalar_mix....00000000.0000000.000000NaN
1basebert-base-uncased-mix_00-edges-rel-semevalbert-base-uncased-mixrel-semeval/edges-rel-semeval/model_state_target_train_va...1.099132__scalar_mix__/nfs/jiant/exp/iftenney/20190721-bert-base-lay...0.000000sent_encoder._text_field_embedder.scalar_mix....00000000.0000000.000000NaN
2basebert-base-uncased-mix_01-edges-coref-ontonotesbert-base-uncased-mixcoref-ontonotes/edges-coref-ontonotes/model_state_target_trai...1.835713__scalar_mix__/nfs/jiant/exp/iftenney/20190721-bert-base-lay...-0.709879sent_encoder._text_field_embedder.scalar_mix....0000000.71120.2888000.8053001.000000
3basebert-base-uncased-mix_01-edges-rel-semevalbert-base-uncased-mixrel-semeval/edges-rel-semeval/model_state_target_train_va...1.097378__scalar_mix__/nfs/jiant/exp/iftenney/20190721-bert-base-lay...-0.178499sent_encoder._text_field_embedder.scalar_mix....0000000.9773780.0226220.5883131.000000
4basebert-base-uncased-mix_02-edges-coref-ontonotesbert-base-uncased-mixcoref-ontonotes/edges-coref-ontonotes/model_state_target_trai...1.777263__scalar_mix__/nfs/jiant/exp/iftenney/20190721-bert-base-lay...-0.585102sent_encoder._text_field_embedder.scalar_mix....0000001.197470.3874941.5505491.805902
\n", - "

5 rows × 40 columns

\n", - "
" - ], - "text/plain": [ - " tag exp_name \\\n", - "0 base bert-base-uncased-mix_00-edges-coref-ontonotes \n", - "1 base bert-base-uncased-mix_00-edges-rel-semeval \n", - "2 base bert-base-uncased-mix_01-edges-coref-ontonotes \n", - "3 base bert-base-uncased-mix_01-edges-rel-semeval \n", - "4 base bert-base-uncased-mix_02-edges-coref-ontonotes \n", - "\n", - " exp_type task \\\n", - "0 bert-base-uncased-mix coref-ontonotes \n", - "1 bert-base-uncased-mix rel-semeval \n", - "2 bert-base-uncased-mix coref-ontonotes \n", - "3 bert-base-uncased-mix rel-semeval \n", - "4 bert-base-uncased-mix coref-ontonotes \n", - "\n", - " checkpoint gamma \\\n", - "0 /edges-coref-ontonotes/model_state_target_trai... 1.731095 \n", - "1 /edges-rel-semeval/model_state_target_train_va... 1.099132 \n", - "2 /edges-coref-ontonotes/model_state_target_trai... 1.835713 \n", - "3 /edges-rel-semeval/model_state_target_train_va... 1.097378 \n", - "4 /edges-coref-ontonotes/model_state_target_trai... 1.777263 \n", - "\n", - " label run \\\n", - "0 __scalar_mix__ /nfs/jiant/exp/iftenney/20190721-bert-base-lay... \n", - "1 __scalar_mix__ /nfs/jiant/exp/iftenney/20190721-bert-base-lay... \n", - "2 __scalar_mix__ /nfs/jiant/exp/iftenney/20190721-bert-base-lay... \n", - "3 __scalar_mix__ /nfs/jiant/exp/iftenney/20190721-bert-base-lay... \n", - "4 __scalar_mix__ /nfs/jiant/exp/iftenney/20190721-bert-base-lay... \n", - "\n", - " scalar_parameters.0 scalar_set \\\n", - "0 0.000000 sent_encoder._text_field_embedder.scalar_mix. \n", - "1 0.000000 sent_encoder._text_field_embedder.scalar_mix. \n", - "2 -0.709879 sent_encoder._text_field_embedder.scalar_mix. \n", - "3 -0.178499 sent_encoder._text_field_embedder.scalar_mix. \n", - "4 -0.585102 sent_encoder._text_field_embedder.scalar_mix. \n", - "\n", - " ... 7 8 9 10 11 12 weight_entropy \\\n", - "0 ... 0 0 0 0 0 0 0 \n", - "1 ... 0 0 0 0 0 0 0 \n", - "2 ... 0 0 0 0 0 0 0.7112 \n", - "3 ... 0 0 0 0 0 0 0.977378 \n", - "4 ... 0 0 0 0 0 0 1.19747 \n", - "\n", - " weight_kl_unif weight_exp_layer weight_exp_layer_oneplus \n", - "0 0.000000 0.000000 NaN \n", - "1 0.000000 0.000000 NaN \n", - "2 0.288800 0.805300 1.000000 \n", - "3 0.022622 0.588313 1.000000 \n", - "4 0.387494 1.550549 1.805902 \n", - "\n", - "[5 rows x 40 columns]" - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Count total scalar columns\n", - "scalar_columns = collections.OrderedDict(sorted(\n", - " [(int(m.group(1)), m.group(0)) for m in \n", - " (re.match(\"^scalar_parameters\\.(\\d+)$\", str(name)) for name in scalar_df.columns)\n", - " if m]\n", - "))\n", - "\n", - "# Fill NaN with -inf for scalar columns\n", - "for name in scalar_columns.values():\n", - " scalar_df[name].fillna(value=-np.inf, inplace=True)\n", - "\n", - "# Pre-fill number columns\n", - "for number in scalar_columns.keys():\n", - " scalar_df[number] = None\n", - "scalar_df[\"weight_entropy\"] = None\n", - " \n", - "# Softmax over parameters in each row\n", - "num_scalars = max(scalar_columns.keys()) + 1\n", - "scalars = {}\n", - "masks = {}\n", - "for i, row in scalar_df.iterrows():\n", - " arr = np.zeros(num_scalars, dtype=np.float32)\n", - " for j, col in scalar_columns.items():\n", - " arr[j] = float(row[col])\n", - " if np.isnan(arr[j]):\n", - " arr[j] = -np.inf\n", - " # Softmax over row\n", - " scalars[i] = softmax(arr)\n", - " masks[i] = np.isfinite(arr)\n", - "\n", - "# Add softmax weights back to DataFrame, with numeric column names.\n", - "# This way, we can convert to long-form for easy plotting.\n", - "for i in scalar_df.index:\n", - " for j in scalar_columns.keys():\n", - " scalar_df.loc[i, j] = scalars[i][j]\n", - " # Compute entropy\n", - " scalar_df.loc[i, \"weight_entropy\"] = entropy(scalars[i], base=2)\n", - " scalar_df.loc[i, \"weight_kl_unif\"] = entropy(scalars[i], qk=masks[i], base=2)\n", - " # Compute expectation\n", - " weighted_layers = scalars[i] * np.arange(len(scalars[i])) * masks[i]\n", - " scalar_df.loc[i, \"weight_exp_layer\"] = np.sum(weighted_layers)\n", - " scalar_df.loc[i, \"weight_exp_layer_oneplus\"] = np.sum(weighted_layers[1:]) / np.sum(scalars[i][1:] * masks[i][1:])\n", - "\n", - "scalar_df.head()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Print scalars from the top layer, in spreadsheet-friendly form:" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - ",tag,exp_name,exp_type,task,checkpoint,gamma,label,run,scalar_parameters.0,scalar_set,scalar_parameters.1,scalar_parameters.2,scalar_parameters.3,scalar_parameters.4,scalar_parameters.5,scalar_parameters.6,scalar_parameters.7,scalar_parameters.8,scalar_parameters.9,scalar_parameters.10,scalar_parameters.11,scalar_parameters.12,display_col,0,1,2,3,4,5,6,7,8,9,10,11,12,weight_entropy,weight_kl_unif,weight_exp_layer,weight_exp_layer_oneplus\n", - "24,base,bert-base-uncased-mix_12-edges-coref-ontonotes,bert-base-uncased-mix,coref-ontonotes,/edges-coref-ontonotes/model_state_target_train_val_73.best.th,1.6825,__scalar_mix__,/nfs/jiant/exp/iftenney/20190721-bert-base-layers//bert-base-uncased-mix_12-edges-coref-ontonotes/run,-0.4338,sent_encoder._text_field_embedder.scalar_mix.,-0.6981,-0.6875,-0.7092,-0.6423,-0.3593,0.0113,0.2223,0.8736,1.3477,0.9775,0.4410,-0.0540,bert-base-uncased-mix (base),0.03805815,0.029217781,0.029529793,0.02889403,0.030893512,0.0410006,0.05939578,0.073342934,0.14067322,0.22599995,0.15608208,0.09127266,0.05563934,3.3368135834156445,0.3636,7.7652,8.0724\n", - "25,base,bert-base-uncased-mix_12-edges-rel-semeval,bert-base-uncased-mix,rel-semeval,/edges-rel-semeval/model_state_target_train_val_33.best.th,1.1048,__scalar_mix__,/nfs/jiant/exp/iftenney/20190721-bert-base-layers//bert-base-uncased-mix_12-edges-rel-semeval/run,-0.0888,sent_encoder._text_field_embedder.scalar_mix.,-0.1982,-0.2256,-0.2404,-0.2409,-0.1616,-0.0567,0.1238,0.2615,0.2689,0.2391,0.1682,0.1238,bert-base-uncased-mix (base),0.069189705,0.062019564,0.06033947,0.059453472,0.059423145,0.06433094,0.07144345,0.08557492,0.09821061,0.09894507,0.09603209,0.08946312,0.08557441,3.6727534867213993,0.0277,6.5956,7.0859\n", - "\n" - ] - } - ], - "source": [ - "matcher = \"_12\"\n", - "sheet_df = scalar_df[scalar_df.exp_name.map(lambda s: matcher in s)]\n", - "print(sheet_df.to_csv(**csv_args))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "jiant", - "language": "python", - "name": "jiant" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.6.8" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/probing/analyze_runs.py b/probing/analyze_runs.py deleted file mode 100755 index 0749ce741..000000000 --- a/probing/analyze_runs.py +++ /dev/null @@ -1,120 +0,0 @@ -#!/usr/bin/env python - -# Convenience script to score a set of runs from the predictions. -# -# Usage: -# python analyze_runs.py -i /path/to/experiments/*/run \ -# -o /tmp/stats.tsv [--parallel n] -# -# Output will be a long-form TSV file containing aggregated and per-class -# predictions for each run. - -import argparse -import collections -import json -import logging as log -import os -import re -import sys -from typing import Iterable, List, Tuple - -import pandas as pd -from tqdm import tqdm - -import analysis -from data import utils - -log.basicConfig(format="%(asctime)s: %(message)s", datefmt="%m/%d %I:%M:%S %p", level=log.INFO) - - -def find_tasks_and_splits(run_path: str) -> List[Tuple[str, str]]: - """Find tasks and splits for a particular run.""" - matcher = r"([\w-]+)_(train|val|test)\.json" - matches = [] - for fname in os.listdir(run_path): - m = re.match(matcher, fname) - if m is None: - continue - matches.append(m.groups()) - if not matches: - log.warning("Warning: no predictions found for run '%s'", run_path) - return matches - - -def get_run_info(run_path: str, log_name="log.log") -> pd.DataFrame: - """Extract some run information from the log text.""" - log_path = os.path.join(run_path, log_name) - if not os.path.isfile(log_path): - log.warning("Warning: no log found for run '%s'", run_path) - return None - train_stats = [] - with open(log_path) as fd: - for line in fd: - m = re.match(r"Trained ([\w-]+) for (\d+) batches or (.+) epochs\w*", line) - if m is None: - continue - r = dict(zip(["task", "num_steps", "num_epochs"], m.groups())) - r["run"] = run_path - r["label"] = "__run_info__" - train_stats.append(r) - return pd.DataFrame.from_records(train_stats) - - -def analyze_run(run_path: str, task: str, split: str) -> pd.DataFrame: - log.info("Analyzing: '%s' / %s' / '%s'", run_path, task, split) - preds = analysis.Predictions.from_run(run_path, task, split) - scores = preds.score_by_label() - # Add identifiers - scores.insert(0, "run", value=run_path) - scores.insert(1, "task", value=task) - scores.insert(2, "split", value=split) - return scores - - -def _analyze_run(item): - return analyze_run(*item) - - -def main(args): - parser = argparse.ArgumentParser() - parser.add_argument("-o", dest="output", type=str, default="", help="Output file (TSV).") - parser.add_argument("-i", dest="inputs", type=str, nargs="+", help="Input files.") - parser.add_argument( - "--parallel", type=int, default=1, help="Number of runs to process in parallel." - ) - args = parser.parse_args(args) - - work_items = [] - run_info = [] - for run_path in args.inputs: - for task, split in find_tasks_and_splits(run_path): - work_items.append((run_path, task, split)) - # Global run info from log file. - run_info.append(get_run_info(run_path)) - - all_scores = [] - if args.parallel > 1: - from multiprocessing import Pool - - log.info("Processing runs in parallel with %d workers", args.parallel) - log.getLogger().setLevel(log.WARNING) # hide INFO spam - pool = Pool(args.parallel) - for score in tqdm(pool.imap_unordered(_analyze_run, work_items), total=len(work_items)): - all_scores.append(score) - log.getLogger().setLevel(log.INFO) # re-enable - else: - for score in tqdm(map(_analyze_run, work_items), total=len(work_items)): - all_scores.append(score) - - long_scores = pd.concat(run_info + all_scores, axis=0, ignore_index=True, sort=False) - - if args.output: - log.info("Writing long-form stats table to %s", args.output) - long_scores.to_csv(args.output, sep="\t") - else: - log.info("Stats:\n%s", str(long_scores)) - - -if __name__ == "__main__": - main(sys.argv[1:]) - sys.exit(0) diff --git a/probing/convert_edge_data_to_tfrecord.py b/probing/convert_edge_data_to_tfrecord.py deleted file mode 100755 index 02e818ee0..000000000 --- a/probing/convert_edge_data_to_tfrecord.py +++ /dev/null @@ -1,102 +0,0 @@ -#!/usr/bin/env python - -# Helper script to convert edge probing JSON data to TensorFlow Examples in -# TFRecord format. -# -# Usage: -# python convert_edge_data_to_tfrecord.py /path/to/data/*.json -# -# New files will have the same basename, with .tfrecord extension, -# e.g. foo_edges.json -> foo_edges.tfrecord - -import json -import logging as log -import os -import sys -from typing import Dict, List - -import tensorflow as tf -from tqdm import tqdm - -from jiant.utils import utils - -log.basicConfig(format="%(asctime)s: %(message)s", datefmt="%m/%d %I:%M:%S %p", level=log.INFO) - - -def add_string_feature(ex: tf.train.Example, name: str, text: str): - """Append a single string to the named feature.""" - if isinstance(text, str): - text = text.encode("utf-8") - ex.features.feature[name].bytes_list.value.append(text) - - -def add_ints_feature(ex: tf.train.Example, name: str, ints: List[int]): - """Append ints from a list to the named feature.""" - ex.features.feature[name].int64_list.value.extend(ints) - - -def convert_to_example(record: Dict): - """Convert an edge probing record to a TensorFlow example. - - The example has the following features: - - text: single string, the text - - targets.span1: list of int64, alternating start, end indices - - targets.span2: (optional), list of int64, as targets.span1 - - targets.label: list of strings (see note below) - - info: single string, serialized info JSON - - targets.info: list of strings, serialized info JSON for each target - - Due to the limitations of tf.Example, spans are packed into a single flat - list of length 2*num_targets containing alternating endpoints: [s0, e0, s1, - e1, ..., sn, en]. You can get individual spans back with tf.reshape(spans, - [-1, 2]). - - If examples have multiple labels per target (such as for SPR2), these are - joined into a single string on spaces: - label: ["foo", "bar", "baz"] -> "foo bar baz" - You can use tf.string_split and tf.sparse.to_dense to convert these into an - array of targets. - - Args: - record: dict, in edge probing record (JSON) format. - - Returns: - tf.train.Example with features described above. - """ - ex = tf.train.Example() - add_string_feature(ex, "text", record["text"]) - add_string_feature(ex, "info", json.dumps(record.get("info", {}))) - for target in record["targets"]: - label_string = " ".join(utils.wrap_singleton_string(target["label"])) - add_string_feature(ex, "targets.label", label_string) - add_ints_feature(ex, "targets.span1", target["span1"]) - if "span2" in target: - add_ints_feature(ex, "targets.span2", target["span2"]) - add_string_feature(ex, "target.info", json.dumps(target.get("info", {}))) - - # Verify that span2 is either empty or aligned to span1. - num_span1s = len(ex.features.feature["targets.span1"].int64_list.value) - num_span2s = len(ex.features.feature["targets.span2"].int64_list.value) - assert num_span2s == num_span1s or num_span2s == 0 - return ex - - -def convert_file(fname): - new_name = os.path.splitext(fname)[0] + ".tfrecord" - log.info("Processing file: %s", fname) - record_iter = utils.load_json_data(fname) - log.info(" saving to %s", new_name) - with tf.python_io.TFRecordWriter(new_name) as writer: - for record in tqdm(record_iter): - example = convert_to_example(record) - writer.write(example.SerializeToString()) - - -def main(args): - for fname in args: - convert_file(fname) - - -if __name__ == "__main__": - main(sys.argv[1:]) - sys.exit(0) diff --git a/probing/data/README.md b/probing/data/README.md deleted file mode 100644 index ee9c7a91f..000000000 --- a/probing/data/README.md +++ /dev/null @@ -1,88 +0,0 @@ -# Edge Probing Datasets - -This directory contains scripts to process the source datasets and generate the JSON data for edge probing tasks. Let `$JIANT_DATA_DIR` be the jiant data directory from the [main README](../../README.md), and make a subdirectory for the edge probing data: - -``` -mkdir $JIANT_DATA_DIR/edges -``` - -The resulting JSON has one example per line, with the structure as described in [jiant/probing/README.md](../README.md). - -## OntoNotes -Tasks: -- Constituents / POS: `edges-constituent-ontonotes`, `edges-nonterminal-ontonotes`, - `edges-pos-ontonotes` -- Entities: `edges-ner-ontonotes` -- SRL: `edges-srl-ontonotes` -- Coreference: `edges-coref-ontonotes-conll` - -### Getting OntoNotes Data -Follow the instructions at http://cemantix.org/data/ontonotes.html; you should end up with a folder named `conll-formatted-ontonotes-5.0/`. - -If you're working on the JSALT cloud project, you can also download this directly from `gs://jsalt-data/ontonotes`. - -### Extracting Data -To extract all OntoNotes tasks, run: -``` -python extract_ontonotes_all.py --ontonotes /path/to/conll-formatted-ontonotes-5.0 \ - --tasks const coref ner srl \ - --splits train development test conll-2012-test \ - -o $JIANT_DATA_DIR/edges/ontonotes -``` -This will write a number of JSON files, one for each split for each task, with names `{task}/{split}.json`. - -### Splitting Constituent Data - -The constituent data from the script above includes both preterminal (POS tag) and nonterminal (constituent) examples. We can split these into the `edges-nonterminal-ontonotes` and `edges-pos-ontonotes` tasks by running: -``` -python jiant/probing/split_constituent_data.py $JIANT_DATA_DIR/edges/ontonotes/const/*.json -``` -This will create `pos/*.json` and `nonterminal/*.json` versions of each input file. - -## Semantic Proto Roles (SPR) - -### SPR1 -Tasks: `edges-spr1` - -The version of SPR1 distributed on [decomp.io](http://decomp.io/) is difficult to work with directly, because it requires joining with both the Penn Treebank and the PropBank SRL annotations. If you have access to the Penn Treebank ([LDC99T42](https://catalog.ldc.upenn.edu/ldc99t42)), contact Rachel Rudinger or Ian Tenney for a processed copy of the data. - -From Rachel's JSON format, you can use a script in this directory to convert to edge probing format: - -``` -./convert-spr1-rudinger.py -i /path/to/spr1/*.json \ - -o $JIANT_DATA_DIR/edges/spr1 -``` - -You should get files named `spr1.{split}.json` where `split = {train, dev, test}`. - -### SPR2 -Tasks: `edges-spr2` - -Run: -``` -pip install conllu -./get_spr2_data.sh $JIANT_DATA_DIR/edges/spr2 -``` - -This downloads both the UD treebank and the annotations and performs a join. See the `get_spr2_data.sh` script for more info. The `conllu` package is required to process the Universal Dependencies source data. - - -## Definite Pronoun Resolution (DPR) - -Tasks: `edges-dpr` - -Run: -``` -./get_dpr_data.sh $JIANT_DATA_DIR/edges/dpr -``` - -## Universal Dependencies - -Tasks: `edges-dep-labeling-ewt` - -Run: -``` -./get_ud_data.sh $JIANT_DATA_DIR/edges/dep_ewt -``` - -This downloads the UD treebank and converts the conllu format to the edge probing format. diff --git a/probing/data/convert-dpr.py b/probing/data/convert-dpr.py deleted file mode 100755 index b132ee356..000000000 --- a/probing/data/convert-dpr.py +++ /dev/null @@ -1,136 +0,0 @@ -#!/usr/bin/env python - -# Script to convert DPR data into edge probing format. -# -# Usage: -# ./convert-dpr.py --src_dir \ -# -o /path/to/probing/data/dpr - -import argparse -import json -import logging as log -import os -import sys - -import pandas as pd -from nltk.tokenize.moses import MosesTokenizer - -log.basicConfig(format="%(asctime)s: %(message)s", datefmt="%m/%d %I:%M:%S %p", level=log.INFO) - - -TOKENIZER = MosesTokenizer() - - -def get_dpr_text(filename): - text2examples = {} - curr = {} - with open(filename) as fd: - for line in fd: - line = line.strip() - if not line: - # store curr - curr_text = curr["text"] - if curr_text not in text2examples: - text2examples[curr_text] = [] - text2examples[curr_text].append(curr) - # make new curr - curr = {} - else: - # get id - line = line.split(":") - key = line[0].strip() - val = " ".join(line[1:]).strip() - curr[key] = val - return text2examples - - -def convert_text_examples_to_json(text, example): - # dict_keys(['provenance', 'index', 'text', 'hypothesis', 'entailed', 'partof']) - # This assert makes sure that no text appears in train and test - tokens = TOKENIZER.tokenize(text) - split = set([ex["partof"] for ex in example]) - assert len(split) == 1 - obj = { - "text": " ".join(tokens), - "info": {"split": list(split)[0], "source": "recast-dpr"}, - "targets": [], - } - for ex in example: - hyp = TOKENIZER.tokenize(ex["hypothesis"]) - assert len(tokens) <= len(hyp) - found_diff_word = False - for idx, pair in enumerate(zip(tokens, hyp)): - if pair[0] != pair[1]: - referent = "" - found_diff_word = True - distance = len(hyp) - len(tokens) + 1 - pro_noun = tokens[idx] - found_referent = False - for word_idx in range(idx + 1): - referent = hyp[idx : idx + distance] - if word_idx == 0: - referent[0] = referent[0][0].upper() + referent[0][1:] - if referent == tokens[word_idx : word_idx + distance]: - found_referent = True - target = { - "span1": [idx, idx + 1], - "span2": [word_idx, word_idx + distance], - "label": ex["entailed"], - "span1_text": pro_noun, - "span2_text": " ".join(tokens[word_idx : word_idx + distance]), - } - obj["targets"].append(target) - break - break - - return obj - - -def convert_dpr(text2examples, output_dir: str): - split_files = { - k: open(os.path.join(output_dir, f"{k}.json"), "w") for k in ["train", "dev", "test"] - } - skip_counter = 0 - - for text, example in text2examples.items(): - record = convert_text_examples_to_json(text, example) - if not record.get("targets", []): - skip_counter += 1 - continue - # Write to file by split key. - split = record["info"]["split"] - split_files[split].write(json.dumps(record)) - split_files[split].write("\n") - log.info("Skipped %d examples with no targets found.", skip_counter) - - -def main(args): - parser = argparse.ArgumentParser() - parser.add_argument( - "--src_dir", - type=str, - required=True, - help="Path to inference_is_everything source data, as passed to get_dpr_data.sh", - ) - parser.add_argument( - "-o", - dest="output_dir", - type=str, - required=True, - help="Output directory, e.g. /path/to/edges/data/dpr", - ) - args = parser.parse_args(args) - - if not os.path.isdir(args.output_dir): - os.mkdir(args.output_dir) - - src_file = os.path.join(args.src_dir, "dpr_data.txt") - text2examples = get_dpr_text(src_file) - log.info("Processing DPR annotations...") - convert_dpr(text2examples, output_dir=args.output_dir) - log.info("Done!") - - -if __name__ == "__main__": - main(sys.argv[1:]) - sys.exit(0) diff --git a/probing/data/convert-semeval2010-task8.py b/probing/data/convert-semeval2010-task8.py deleted file mode 100755 index e88b90923..000000000 --- a/probing/data/convert-semeval2010-task8.py +++ /dev/null @@ -1,122 +0,0 @@ -#!/usr/bin/env python - -# Script to convert SemEval 2010 Task 8 data into edge probing format. -# -# Download the data from -# https://docs.google.com/document/d/1QO_CnmvNRnYwNWu1-QCAeR5ToQYkXUqFeAJbdEhsq7w/preview -# (yes, that's actually the website) and unzip SemEval2010_task8_all_data.zip -# -# Usage: -# ./convert-semeval2010-task8.py \ -# -i /SemEval2010_task8_/.txt \ -# -o /path/to/probing/data/semeval-2010-task8/.json -# - -import argparse -import collections -import json -import logging as log -import os -import re -import sys -from typing import Dict, Iterable, Tuple - -import numpy as np -import pandas as pd -from tqdm import tqdm - -import utils - -log.basicConfig(format="%(asctime)s: %(message)s", datefmt="%m/%d %I:%M:%S %p", level=log.INFO) - - -def parse_lines(lines: Iterable[str]) -> Iterable[Tuple[str, str, str]]: - """Parse the SemEval 2010 data format. - - See SemEval2018_task8_all_data/SemEval2010_task8_training/README.txt - Format is: - - 12 "Text of the sentence with entity tags" - Label(e1, e2) - Comment: text from the annotator explaining the label - """ - current = [] - for line in lines: - if not line.strip(): - if current: - assert len(current) == 3 - yield tuple(current) - current = [] - continue - current.append(line) - if current: - assert len(current) == 3 - yield tuple(current) - - -TAG_MATCHER = r"" -TAG_MATCHER_START = r".*.*" -TAG_MATCHER_END = r".*.*" - - -def get_entity_spans(tagged_tokens): - spans = collections.defaultdict(lambda: [None, None]) - for i, token in enumerate(tagged_tokens): - m = re.match(TAG_MATCHER_START, token) - if m: - spans[int(m.group(1))][0] = i # inclusive - m = re.match(TAG_MATCHER_END, token) - if m: - spans[int(m.group(1))][1] = i + 1 # exclusive - spans.default_factory = None - # Validate spans to make sure both are complete. - assert set(spans.keys()) == {1, 2} - for span in spans.values(): - assert len(span) == 2 - assert span[0] is not None - assert span[1] is not None - return spans - - -def record_from_triple(sentence_line, label, comment_line): - record = {} - m = re.match(r'^(\d+)\s+"(.*)"\s*$', sentence_line) - assert m is not None - id, tagged_sentence = m.groups() - tagged_tokens = tagged_sentence.split() - clean_tokens = [re.sub(TAG_MATCHER, "", t) for t in tagged_tokens] - record["text"] = " ".join(clean_tokens) - record["info"] = {"id": int(id)} - - spans = get_entity_spans(tagged_tokens) - target = {} - target["label"] = label - target["span1"] = spans[1] - target["span2"] = spans[2] - target["info"] = {"comment": re.sub(r"Comment:\s*", "", comment_line)} - record["targets"] = [target] - return record - - -def convert_file(fname: str, target_fname: str): - triples = parse_lines(utils.load_lines(fname)) - records = (record_from_triple(*t) for t in triples) - utils.write_file_and_print_stats(records, target_fname) - - -def main(args): - parser = argparse.ArgumentParser() - parser.add_argument( - "-i", dest="input", type=str, required=True, help="Input .TXT file with SemEval examples." - ) - parser.add_argument("-o", dest="output", type=str, required=True, help="Output .json file.") - args = parser.parse_args(args) - - pd.options.display.float_format = "{:.2f}".format - log.info("Converting %s", args.input) - convert_file(args.input, args.output) - - -if __name__ == "__main__": - main(sys.argv[1:]) - sys.exit(0) diff --git a/probing/data/convert-spr1-rudinger.py b/probing/data/convert-spr1-rudinger.py deleted file mode 100755 index 6704ffc6b..000000000 --- a/probing/data/convert-spr1-rudinger.py +++ /dev/null @@ -1,118 +0,0 @@ -#!/usr/bin/env python - -# Script to convert SPR1 data from Rachel Rudinger's JSON format used for -# (https://arxiv.org/pdf/1804.07976.pdf) into edge probing format. -# -# Note that reconstructing SPR1 from the raw data available on decomp.net is -# considerably more difficult. TODO to check in a full pipeline of scripts to -# join against PTB and PropBank annotations. -# -# Usage: -# ./convert-spr1-rudinger.py -i /path/to/spr1/*.json \ -# -o /path/to/probing/data/spr1/ -# -# This will print a bunch of stats for each file, which you can sanity-check -# against the published size of the dataset. -# -# Input should be JSON with a single record per line, with a format similar to: -# {'tokens': ['William', 'Craig', ',', 'an', 'independent', 'record', -# 'promoter', ',', 'pleaded', 'guilty', 'to', 'payola', 'and', -# 'criminal', 'tax', 'charges', ',', 'according', 'to', 'a', -# 'statement', 'issued', 'by', 'Gary', 'Feess', ',', 'the', -# 'U.S.', 'attorney', 'here', '.'], -# 'pb': [], -# 'wsd': [], -# 'split': 'dev', -# 'fn': [], -# 'sent_id': '1940_1', -# 'spr1': [ -# {'alignment_src': 'alignment_loss_00', -# 'arg_idx': 11, -# 'pred_idx': 8, -# 'responses': [{'spr_property': 'awareness', 'response': 1.0}, -# {'spr_property': 'change_of_location', 'response': 1.0}, -# {'spr_property': 'change_of_state', 'response': 5.0}, -# ... -# {'spr_property': 'created', 'response': 1.0}, -# {'spr_property': 'destroyed', 'response': 1.0}] -# }, -# {'alignment_src': 'alignment_loss_00', -# 'arg_idx': 1, -# 'pred_idx': 8, -# 'responses': [{'spr_property': 'awareness', 'response': 5.0}, -# {'spr_property': 'change_of_location', 'response': 3.0}, -# ... -# {'spr_property': 'change_of_state', 'response': 4.0},] -# } -# ... -# ] -# } - -import argparse -import collections -import json -import logging as log -import os -import sys -from typing import Dict, Iterable - -import numpy as np -import pandas as pd -from tqdm import tqdm - -import utils - -log.basicConfig(format="%(asctime)s: %(message)s", datefmt="%m/%d %I:%M:%S %p", level=log.INFO) - - -def binarize_labels(responses): - scores_by_property = collections.defaultdict(lambda: []) - for response in responses: - scores_by_property[response["spr_property"]] = response["response"] - avg_scores = {k: np.mean(v) for k, v in scores_by_property.items()} - bin_scores = {k: (v > 3.0) for k, v in avg_scores.items()} - pos_labels = [k for k, v in bin_scores.items() if v] - return sorted(pos_labels) - - -def convert_record(source_record): - record = {} - record["text"] = " ".join(source_record["tokens"]) - record["info"] = dict(split=source_record["split"], sent_id=source_record["sent_id"]) - targets = [] - for source_target in source_record["spr1"]: - p = source_target["pred_idx"] # token index - a = source_target["arg_idx"] # token index - labels = binarize_labels(source_target["responses"]) - targets.append(dict(span1=[p, p + 1], span2=[a, a + 1], label=labels)) - record["targets"] = targets - return record - - -def main(args): - parser = argparse.ArgumentParser() - parser.add_argument( - "-i", dest="inputs", type=str, nargs="+", help="Input files (JSON) for SPR1 splits." - ) - parser.add_argument("-o", dest="output_dir", type=str, required=True, help="Output directory.") - args = parser.parse_args(args) - - if not os.path.isdir(args.output_dir): - os.mkdir(args.output_dir) - - pd.options.display.float_format = "{:.2f}".format - for fname in args.inputs: - log.info("Converting %s", fname) - source_records = list(utils.load_json_data(fname)) - converted_records = (convert_record(r) for r in tqdm(source_records)) - stats = utils.EdgeProbingDatasetStats() - converted_records = stats.passthrough(converted_records) - target_fname = os.path.join(args.output_dir, os.path.basename(fname)) - utils.write_json_data(target_fname, converted_records) - log.info("Wrote examples to %s", target_fname) - log.info(stats.format()) - - -if __name__ == "__main__": - main(sys.argv[1:]) - sys.exit(0) diff --git a/probing/data/convert-spr2.py b/probing/data/convert-spr2.py deleted file mode 100755 index 51c447ea2..000000000 --- a/probing/data/convert-spr2.py +++ /dev/null @@ -1,144 +0,0 @@ -#!/usr/bin/env python - -# Script to convert SPR2 data into edge probing format. -# Run get_spr2_data.sh first to download the data. -# -# Usage: -# ./convert-spr2.py --src_dir \ -# -o /path/to/probing/data/spr2 - -import argparse -import json -import logging as log -import os -import sys - -import conllu -import pandas as pd - -log.basicConfig(format="%(asctime)s: %(message)s", datefmt="%m/%d %I:%M:%S %p", level=log.INFO) - - -def load_ud_corpus(ud_source_dir: str): - """ - Extracts the underlying UD corpus data that is stored in conllu format. - Returns a dictionary where the keys are the split and the values are dictionaries - where the keys are the sentenceId - """ - data_path = os.path.join(ud_source_dir, "UD_English-EWT-r1.2") - - sent_id_to_text = {} - for split in ["train", "dev", "test"]: - split_path = os.path.join(data_path, f"en-ud-{split}.conllu") - log.info("Loading UD data from %s", split_path) - with open(split_path) as fd: - data = "".join(line for line in fd) - data = conllu.parse(data) - sent_count = 0 - for sent in data: - sent_id_to_text[(split, sent_count)] = " ".join([item["form"] for item in sent]) - sent_count += 1 - - return sent_id_to_text - - -def convert_spr(sent_id_to_text, protoroles_source_dir: str, output_dir: str): - sent_id2pred_arg_pairs = {} - sent_id2targets = {} - annotations_csv_path = os.path.join(protoroles_source_dir, "protoroles_eng_ud1.2_11082016.tsv") - df = pd.read_csv(annotations_csv_path, sep="\t", header=0) - for df_idx, row in df.iterrows(): - if row["Applicable"] == "no": - continue - id_pair = row["Sentence.ID"].split() - assert len(id_pair) == 2 - split = id_pair[0].split(".con")[0].split("-")[-1] - sent_id = id_pair[1] - sent_text = sent_id_to_text[split, int(sent_id) - 1] - if (split, sent_id) not in sent_id2targets: - sent_id2targets[(split, sent_id)] = { - "targets": [], - "info": { - "source": "SPR2", - "sent-id": sent_id, - "split": split, - "grammatical": row["Sent.Grammatical"], - }, - } - sent_id2pred_arg_pairs[(split, sent_id)] = {} - - # span1 is predicate, span2 is argument - span1 = (row["Pred.Token"], row["Pred.Token"] + 1) - span2 = (row["Arg.Tokens.Begin"], row["Arg.Tokens.End"] + 1) - if (span1, span2) not in sent_id2pred_arg_pairs[(split, sent_id)]: - sent_id2pred_arg_pairs[(split, sent_id)][(span1, span2)] = { - "span2": list(span2), - "span1": list(span1), - "label": {}, - "info": { - "span2_txt": row["Arg.Phrase"], - "span1_text": sent_text.split()[row["Pred.Token"]], - "is_pilot": row["Is.Pilot"], - "pred_lemma": row["Pred.Lemma"], - }, - } - - _properties = sent_id2pred_arg_pairs[(split, sent_id)][(span1, span2)]["label"] - if row["Property"] not in _properties: - sent_id2pred_arg_pairs[(split, sent_id)][(span1, span2)]["label"][row["Property"]] = [] - sent_id2pred_arg_pairs[(split, sent_id)][(span1, span2)]["label"][row["Property"]].append( - row["Response"] - ) - - outfiles = {} - for key in sent_id2targets: - val = sent_id2targets[key] - val["text"] = sent_id_to_text[key[0], int(key[1]) - 1] - val["info"]["split"] = key[0] - val["info"]["sent_id"] = key[1] - for span_pair in sent_id2pred_arg_pairs[key]: - labels = sent_id2pred_arg_pairs[key][span_pair]["label"] - sent_id2pred_arg_pairs[key][span_pair]["label"] = [ - key for key, val in labels.items() if sum(val) / float(len(val)) >= 4.0 - ] - val["targets"].append(sent_id2pred_arg_pairs[key][span_pair]) - - data_split = val["info"]["split"] - if data_split not in outfiles: - output_file = os.path.join(output_dir, f"edges.{data_split}.json") - outfiles[data_split] = open(output_file, "w") - json.dump(val, outfiles[data_split]) - outfiles[data_split].write("\n") - - -def main(args): - parser = argparse.ArgumentParser() - parser.add_argument( - "--src_dir", - type=str, - required=True, - help="Path to source data (SPR and UD1.2), as passed " "to get_spr_data.sh", - ) - parser.add_argument( - "-o", - dest="output_dir", - type=str, - required=True, - help="Output directory, e.g. /path/to/edges/data/spr2", - ) - args = parser.parse_args(args) - - if not os.path.isdir(args.output_dir): - os.mkdir(args.output_dir) - - sent_id_to_text = load_ud_corpus(os.path.join(args.src_dir, "ud")) - log.info("Processing proto-role annotations...") - convert_spr( - sent_id_to_text, os.path.join(args.src_dir, "protoroles"), output_dir=args.output_dir - ) - log.info("Done!") - - -if __name__ == "__main__": - main(sys.argv[1:]) - sys.exit(0) diff --git a/probing/data/extract_ontonotes_all.py b/probing/data/extract_ontonotes_all.py deleted file mode 100644 index 06ef0efb2..000000000 --- a/probing/data/extract_ontonotes_all.py +++ /dev/null @@ -1,204 +0,0 @@ -import collections -import json -import logging as log -import os -import sys -from typing import Dict, List, Tuple - -import numpy as np -from allennlp.data.dataset_readers.dataset_utils import Ontonotes -from allennlp.data.dataset_readers.dataset_utils.span_utils import bio_tags_to_spans -from tqdm import tqdm - -import utils - -log.basicConfig(format="%(asctime)s: %(message)s", datefmt="%m/%d %I:%M:%S %p", level=log.INFO) - - -def _incl_to_excl(span: Tuple[int, int]): - return (span[0], span[1] + 1) - - -def _make_target(label: List[str], span1: Tuple[int, int], span2: Tuple[int, int] = None): - t = {"span1": _incl_to_excl(span1), "label": label} - if span2 is not None: - t["span2"] = _incl_to_excl(span2) - return t - - -def make_record(spans, sentence): - record = {} - record["info"] = {"document_id": sentence.document_id, "sentence_id": sentence.sentence_id} - - record["text"] = " ".join(sentence.words) - record["targets"] = [_make_target(*s) for s in spans] - return record - - -def constituents_to_record(parse_tree): - """Function converting Tree object to dictionary compatible with common JSON format - copied from ptb_process.py so it doesn't have dependencies - """ - form_function_discrepancies = ["ADV", "NOM"] - grammatical_rule = ["DTV", "LGS", "PRD", "PUT", "SBJ", "TPC", "VOC"] - adverbials = ["BNF", "DIR", "EXT", "LOC", "MNR", "PRP", "TMP"] - miscellaneous = ["CLR", "CLF", "HLN", "TTL"] - punctuations = ["-LRB-", "-RRB-", "-LCB-", "-RCB-", "-LSB-", "-RSB-"] - - record = {} - record["text"] = " ".join(parse_tree.flatten()) - record["targets"] = [] - - max_height = parse_tree.height() - for i, leaf in enumerate(parse_tree.subtrees(lambda t: t.height() == 2)): - # modify the leafs by adding their index in the parse_tree - leaf[0] = (leaf[0], str(i)) - - for index, subtree in enumerate(parse_tree.subtrees()): - assoc_words = subtree.leaves() - assoc_words = [(i, int(j)) for i, j in assoc_words] - assoc_words.sort(key=lambda elem: elem[1]) - tmp_tag_list = subtree.label().replace("=", "-").replace("|", "-").split("-") - label = tmp_tag_list[0] - if tmp_tag_list[-1].isdigit(): # Getting rid of numbers at the end of each tag - fxn_tgs = tmp_tag_list[1:-1] - else: - fxn_tgs = tmp_tag_list[1:] - # Special cases: - if len(tmp_tag_list) > 1 and tmp_tag_list[1] == "S": # Case when we have 'PRP-S' or 'WP-S' - label = tmp_tag_list[0] + "-" + tmp_tag_list[1] - fxn_tgs = tmp_tag_list[2:-1] if tmp_tag_list[-1].isdigit() else tmp_tag_list[2:] - if ( - subtree.label() in punctuations - ): # Case when we have one of the strange punctions, such as round brackets - label, fxn_tgs = subtree.label(), [] - target = {"span1": [int(assoc_words[0][1]), int(assoc_words[-1][1]) + 1], "label": label} - - fxn_tgs = set(fxn_tgs) - target["info"] = { - "height": subtree.height() - 1, - # "depth": find_depth(parse_tree, subtree), - "form_function_discrepancies": list(fxn_tgs.intersection(form_function_discrepancies)), - "grammatical_rule": list(fxn_tgs.intersection(grammatical_rule)), - "adverbials": list(fxn_tgs.intersection(adverbials)), - "miscellaneous": list(fxn_tgs.intersection(miscellaneous)), - } - record["targets"].append(target) - - return record - - -def find_links(span_list): - pairs = [] - for i, span1 in enumerate(span_list): - for span2 in span_list[i + 1 :]: - pairs.append((str(int(span1[0] == span2[0])), span1[1], span2[1])) - return pairs - - -def get_frames(sentence): - for frame, bio_tags in sentence.srl_frames: - frame_targets = [] - spans = bio_tags_to_spans(bio_tags) - head_span = None - other_spans = [] - for (tag, indices) in spans: - if tag == "V": - head_span = indices - else: - other_spans.append((tag, indices)) - if head_span is None: - print(frame, bio_tags) - for span2_tag, span2 in other_spans: - frame_targets.append((span2_tag, head_span, span2)) - yield frame_targets - - -def process_task_split(ontonotes_reader, task: str, stats: collections.Counter): - for sentence in ontonotes_reader: - if task == "ner": - spans = bio_tags_to_spans(sentence.named_entities) - yield make_record(spans, sentence) - elif task == "const": - if sentence.parse_tree is not None: - record = constituents_to_record(sentence.parse_tree) - record["info"] = { - "document_id": sentence.document_id, - "sentence_id": sentence.sentence_id, - } - yield record - else: - stats["missing_tree"] += 1 - yield make_record([], sentence) - elif task == "coref": - spans = find_links(list(sentence.coref_spans)) - yield make_record(spans, sentence) - stats["num_entities"] += len(sentence.coref_spans) - elif task == "srl": - for frame_spans in get_frames(sentence): - yield make_record(frame_spans, sentence) - stats["frames"] += 1 - else: - raise ValueError(f"Unrecognized task '{task}'") - - stats["sentences"] += 1 - - -def main(args): - import argparse - - parser = argparse.ArgumentParser() - parser.add_argument( - "--ontonotes", - type=str, - required=True, - help="Path to OntoNotes, e.g. /path/to/conll-formatted-ontonotes-5.0", - ) - parser.add_argument( - "--tasks", type=str, nargs="+", help="Tasks, one or more of {const, coref, ner, srl}." - ) - parser.add_argument( - "--splits", - type=str, - nargs="+", - default=["train", "development", "test", "conll-2012-test"], - help="Splits, one or more of {train, development, test, conll-2012-test}.", - ) - parser.add_argument( - "-o", dest="output_dir", type=str, default=".", help="Output directory for JSON files." - ) - args = parser.parse_args(args) - - if not os.path.isdir(args.output_dir): - os.mkdir(args.output_dir) - - import pandas as pd - - pd.options.display.float_format = "{:.2f}".format - - # Load OntoNotes reader. - ontonotes = Ontonotes() - for split in args.splits: - for task in args.tasks: - source_path = os.path.join(args.ontonotes, "data", split) - ontonotes_reader = ontonotes.dataset_iterator(file_path=source_path) - - log.info("Processing split '%s' for task '%s'", split, task) - task_dir = os.path.join(args.output_dir, task) - if not os.path.isdir(task_dir): - os.mkdir(task_dir) - target_fname = os.path.join(task_dir, f"{split}.json") - ontonotes_stats = collections.Counter() - converted_records = process_task_split(tqdm(ontonotes_reader), task, ontonotes_stats) - - stats = utils.EdgeProbingDatasetStats() - converted_records = stats.passthrough(converted_records) - utils.write_json_data(target_fname, converted_records) - log.info("Wrote examples to %s", target_fname) - log.info(stats.format()) - log.info(str(pd.Series(ontonotes_stats, dtype=object))) - - -if __name__ == "__main__": - main(sys.argv[1:]) - sys.exit(0) diff --git a/probing/data/get_dpr_data.sh b/probing/data/get_dpr_data.sh deleted file mode 100755 index 94a5006da..000000000 --- a/probing/data/get_dpr_data.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/bash - -TARGET_DIR=$1 - -THIS_DIR=$(realpath $(dirname $0)) - -set -e -if [ ! -d $TARGET_DIR ]; then - mkdir $TARGET_DIR -fi - -function fetch_data() { - mkdir -p $TARGET_DIR/raw - pushd $TARGET_DIR/raw - - # DPR data, as part of diverse NLI corpus (DNC), - # a.k.a. "Inference is Everything" - wget https://github.com/decompositional-semantics-initiative/DNC/raw/master/inference_is_everything.zip - unzip inference_is_everything - - popd -} - -fetch_data - -# Convert DPR to edge probing JSON format. -python $THIS_DIR/convert-dpr.py --src_dir $TARGET_DIR/raw -o $TARGET_DIR - -# Print dataset stats for sanity-check. -python ${THIS_DIR%jiant*}/jiant/probing/edge_data_stats.py -i $TARGET_DIR/*.json - diff --git a/probing/data/get_semeval_data.sh b/probing/data/get_semeval_data.sh deleted file mode 100755 index 81ca8cde6..000000000 --- a/probing/data/get_semeval_data.sh +++ /dev/null @@ -1,47 +0,0 @@ -#!/bin/bash - -TARGET_DIR=$1 - -THIS_DIR=$(realpath $(dirname $0)) - -set -e -if [ ! -d $TARGET_DIR ]; then - mkdir $TARGET_DIR -fi - -# Download link for SemEval 2010 Task 8 data. -# This is a Google Drive link, but it seems to be the official one. -# For the website, see -# https://docs.google.com/document/d/1QO_CnmvNRnYwNWu1-QCAeR5ToQYkXUqFeAJbdEhsq7w/preview -SEMEVAL_URL="https://drive.google.com/uc?authuser=0&id=0B_jQiLugGTAkMDQ5ZjZiMTUtMzQ1Yy00YWNmLWJlZDYtOWY1ZDMwY2U4YjFk&export=download" - -function fetch_data() { - mkdir -p $TARGET_DIR/raw - pushd $TARGET_DIR/raw - - # SemEval 2010 Task 8 official distribution (train and test). - ZIPFILE_NAME="SemEval2010_task8_all_data.zip" - wget "${SEMEVAL_URL}" -O "${ZIPFILE_NAME}" - unzip "${ZIPFILE_NAME}" - - popd -} - -fetch_data - -# Convert SemEval to edge probing format. -TRAIN_SOURCE="$TARGET_DIR/raw/SemEval2010_task8_all_data/SemEval2010_task8_training/TRAIN_FILE.TXT" -TEST_SOURCE="$TARGET_DIR/raw/SemEval2010_task8_all_data/SemEval2010_task8_testing_keys/TEST_FILE_FULL.TXT" -python $THIS_DIR/convert-semeval2010-task8.py -i "${TRAIN_SOURCE}" \ - -o "$TARGET_DIR/train.all.json" -python $THIS_DIR/convert-semeval2010-task8.py -i "${TEST_SOURCE}" \ - -o "$TARGET_DIR/test.json" - -# SemEval 2010 doesn't have an official development set, -# so create one by a (deterministic) random sample of the training data. -python ${THIS_DIR%jiant*}/jiant/probing/deterministic_split.py \ - -s 42 -f 0.85 -i "${TARGET_DIR}/train.all.json" \ - -o "${TARGET_DIR}/train.0.85.json" "${TARGET_DIR}/dev.json" - -# Print dataset stats for sanity-check. -python ${THIS_DIR%jiant*}/jiant/probing/edge_data_stats.py -i $TARGET_DIR/*.json diff --git a/probing/data/get_spr2_data.sh b/probing/data/get_spr2_data.sh deleted file mode 100755 index 30c8a7aa5..000000000 --- a/probing/data/get_spr2_data.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/bin/bash - -TARGET_DIR=$1 - -THIS_DIR=$(realpath $(dirname $0)) - -set -e -if [ ! -d $TARGET_DIR ]; then - mkdir $TARGET_DIR -fi - -function fetch_data() { - mkdir -p $TARGET_DIR/raw - pushd $TARGET_DIR/raw - - # Univeral Dependencies 1.2 for English Web Treebank (ewt) source text. - wget https://github.com/UniversalDependencies/UD_English/archive/r1.2.tar.gz - mkdir ud - tar -zxvf r1.2.tar.gz -C ud - - # Semantic Proto Roles annotations. - wget http://decomp.io/projects/semantic-proto-roles/protoroles_eng_udewt.tar.gz - mkdir protoroles - tar -xvzf protoroles_eng_udewt.tar.gz -C protoroles - - popd -} - -fetch_data - -# Join UD with protorole annotations. -python $THIS_DIR/convert-spr2.py --src_dir $TARGET_DIR/raw -o $TARGET_DIR - -# Print dataset stats for sanity-check. -python ${THIS_DIR%jiant*}/jiant/probing/edge_data_stats.py -i $TARGET_DIR/*.json diff --git a/probing/data/get_ud_data.sh b/probing/data/get_ud_data.sh deleted file mode 100755 index 83562cb00..000000000 --- a/probing/data/get_ud_data.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/bin/bash - -TARGET_DIR=$1 - -THIS_DIR=$(realpath $(dirname $0)) - -set -e -if [ ! -d $TARGET_DIR ]; then - mkdir $TARGET_DIR -fi - -function fetch_data() { - mkdir -p $TARGET_DIR/raw - pushd $TARGET_DIR/raw - - # Univeral Dependencies 2.2 for English Web Treebank (ewt) source text. - wget https://github.com/UniversalDependencies/UD_English-EWT/archive/r2.2.tar.gz - mkdir ud - tar -zxvf r2.2.tar.gz -C ud - - # # Universal Dependencies v2.3 data - # git clone https://github.com/UniversalDependencies/UD_English-EWT.git $TARGET_DIR/raw - - popd -} - -fetch_data - -# Convert UD to edge probing format. -python $THIS_DIR/ud_to_json.py \ - -i $TARGET_DIR/raw/ud/UD_English-EWT-r2.2/en_ewt-ud-*.conllu \ - -o $TARGET_DIR - -# Print dataset stats for sanity-check. -python ${THIS_DIR%jiant*}/jiant/probing/edge_data_stats.py -i $TARGET_DIR/*.json diff --git a/probing/data/ud_to_json.py b/probing/data/ud_to_json.py deleted file mode 100755 index ecdcfacb5..000000000 --- a/probing/data/ud_to_json.py +++ /dev/null @@ -1,124 +0,0 @@ -#!/usr/bin/env python - -# Script to convert UD English Web Treebank (EWT) data intoa -# edge probing format for dependency parsing. -# -# Usage: -# ./ud_to_json.py -i /en_ewt-ud-*.conllu \ -# -o /path/to/probing/data/ud_ewt - -import argparse -import json -import logging as log -import os -import sys - -import conllu -import pandas as pd - -import utils - -log.basicConfig(format="%(asctime)s: %(message)s", datefmt="%m/%d %I:%M:%S %p", level=log.INFO) - - -def convert_ud_file(fd): - """Convert a UD file to a list of records in edge probing format. - - Args: - fd: file-like object or list of lines - - Returns: - list(dict) of edge probing records - """ - # TODO(Tom): refactor to use conllu to parse file - prev_line = "FILLER" - word_lines = [] - examples = [] - - for line in fd: - example_good = 1 - if len(prev_line) < 3: - spans = [] - words = [] - - for word_line in word_lines: - parts = word_line.split("\t") - words.append(parts[1].replace('"', '\\"')) - if "." not in parts[0]: - this_id = int(parts[0]) - this_head = int(parts[6]) - else: - example_good = 0 - this_id = 0 - this_head = 0 - if this_head == 0: - this_head = this_id - deprel = parts[7] - spans.append( - '{"span1": [' - + str(this_id - 1) - + ", " - + str(this_id) - + '], "span2": [' - + str(this_head - 1) - + ", " - + str(this_head) - + '], "label": "' - + deprel - + '"}' - ) - - if example_good: - examples.append( - '{"text": "' - + " ".join(words) - + '", "targets": [' - + ", ".join(spans) - + '], "info": {"source": "UD_English-EWT"}}' - ) - - word_lines = [] - - elif line[0] != "#" and len(line.strip()) > 1: - word_lines.append(line) - - prev_line = line.strip() - - # Stopgap: make sure the JSON is valid. - return [json.loads(e) for e in examples] - - -def main(args): - parser = argparse.ArgumentParser() - parser.add_argument( - "-i", dest="input_files", type=str, nargs="+", help="Input file(s), e.g. en_ewt-ud-*.conllu" - ) - parser.add_argument( - "-o", - dest="output_dir", - type=str, - required=True, - help="Output directory, e.g. /path/to/edges/data/ud_ewt", - ) - args = parser.parse_args(args) - - if not os.path.isdir(args.output_dir): - os.mkdir(args.output_dir) - - for filename in args.input_files: - with open(filename) as fd: - records = convert_ud_file(fd) - stats = utils.EdgeProbingDatasetStats() - records = stats.passthrough(records) - target_basename = os.path.basename(filename).replace(".conllu", ".json") - target_fname = os.path.join(args.output_dir, target_basename) - utils.write_json_data(target_fname, records) - log.info("Wrote examples to %s", target_fname) - log.info(stats.format()) - - log.info("Done!") - - -if __name__ == "__main__": - main(sys.argv[1:]) - sys.exit(0) diff --git a/probing/data/utils.py b/probing/data/utils.py deleted file mode 100644 index 0ceed57a0..000000000 --- a/probing/data/utils.py +++ /dev/null @@ -1,109 +0,0 @@ -import collections -import json -import logging as log -from typing import Dict, Iterable, Sequence, Union - -import numpy as np -import pandas as pd - -log.basicConfig(format="%(asctime)s: %(message)s", datefmt="%m/%d %I:%M:%S %p", level=log.INFO) - - -def load_lines(filename: str) -> Iterable[str]: - """ Load text data, yielding each line. """ - with open(filename) as fd: - for line in fd: - yield line.strip() - - -def load_json_data(filename: str) -> Iterable: - """ Load JSON records, one per line. """ - with open(filename, "r") as fd: - for line in fd: - yield json.loads(line) - - -def write_json_data(filename: str, records: Iterable[Dict]): - """ Write JSON records, one per line. """ - with open(filename, "w") as fd: - for record in records: - fd.write(json.dumps(record)) - fd.write("\n") - - -def wrap_singleton_string(item: Union[Sequence, str]): - """ Wrap a single string as a list. """ - if isinstance(item, str): - # Can't check if iterable, because a string is an iterable of - # characters, which is not what we want. - return [item] - return item - - -class EdgeProbingDatasetStats(object): - def __init__(self): - self._stats = collections.Counter() - - def update(self, record: Dict): - stats = self._stats - - stats["count"] += 1 - tokens = record["text"].split() - stats["token.count"] += len(tokens) - stats["token.count2"] += len(tokens) ** 2 # for computing RMS - stats["token.max_count"] = max(len(tokens), stats["token.max_count"]) - - # Target stats - targets = record.get("targets", []) - stats["targets.count"] += len(targets) - stats["targets.max_count"] = max(len(targets), stats["targets.max_count"]) - for target in targets: - labels = wrap_singleton_string(target["label"]) - stats["targets.label.count"] += len(labels) - span1 = target.get("span1", [-1, -1]) - stats["targets.span1.length"] += max(span1) - min(span1) - span2 = target.get("span2", [-1, -1]) - stats["targets.span2.length"] += max(span2) - min(span2) - - def compute(self, record_iter: Iterable[Dict]): - for record in record_iter: - self.update(record) - - def passthrough(self, record_iter: Iterable[Dict]): - for record in record_iter: - self.update(record) - yield record - - def to_series(self, **kw): - stats = self._stats - s = pd.Series(kw, dtype=object) - s["count"] = stats["count"] - s["token.count"] = stats["token.count"] - s["token.mean_count"] = stats["token.count"] / stats["count"] - s["token.rms_count"] = np.sqrt(stats["token.count2"] / stats["count"]) - s["token.max_count"] = stats["token.max_count"] - s["targets.count"] = stats["targets.count"] - s["targets.mean_count"] = stats["targets.count"] / stats["count"] - s["targets.max_count"] = stats["targets.max_count"] - s["targets.label.count"] = stats["targets.label.count"] - s["targets.label.mean_count"] = stats["targets.label.count"] / stats["targets.count"] - s["targets.span1.mean_length"] = stats["targets.span1.length"] / stats["targets.count"] - s["targets.span2.mean_length"] = stats["targets.span2.length"] / stats["targets.count"] - return s - - def format(self, **kw): - s = self.to_series(**kw) - return "Stats:\n%s\n" % str(s) - - def __str__(self): - return self.format() - - -def write_file_and_print_stats(records: Iterable[Dict], target_fname: str): - """ Write edge probing records to a JSON file, and print dataset stats. """ - stats = EdgeProbingDatasetStats() - records = stats.passthrough(records) - write_json_data(target_fname, records) - log.info("Wrote examples to %s", target_fname) - log.info(stats.format()) - return stats diff --git a/probing/deterministic_split.py b/probing/deterministic_split.py deleted file mode 100755 index d776e9d08..000000000 --- a/probing/deterministic_split.py +++ /dev/null @@ -1,69 +0,0 @@ -#!/usr/bin/env python - -# Helper script to determinstically, but pseudo-randomly split a file by lines. -# This is easy to to with UNIX tools (shuf and split), but the former may -# behave differently on different systems. For repeatability, we implement this -# using a seeded RNG in Python instead. -# -# Usage, to split 'all.txt' into 'train.txt' and 'dev.txt', with train -# containing approximately 80% of the examples: -# python deterministic_split.py -s 42 -f 0.8 -i all.txt -o train.txt dev.txt -# -# Note: this /should/ be reproducible in future Python versions, but may -# require a minor code change to use backwards-compatible RNG seeding. -# See https://docs.python.org/3/library/random.html#notes-on-reproducibility -# -# For edge probing experiments, this is run using Python 3.6.8 - -import argparse -import logging as log -import os -import random -import sys - -from tqdm import tqdm - -log.basicConfig(format="%(asctime)s: %(message)s", datefmt="%m/%d %I:%M:%S %p", level=log.INFO) - - -def main(args): - parser = argparse.ArgumentParser() - parser.add_argument("-s", "--seed", dest="seed", type=int, default=42, help="Random seed.") - parser.add_argument( - "-f", - "--fraction", - dest="fraction", - type=float, - required=True, - help="Fraction to send to first output file.", - ) - parser.add_argument("-i", dest="input", type=str, required=True, help="Input file.") - parser.add_argument( - "-o", dest="outputs", type=str, required=True, nargs=2, help="Output files." - ) - args = parser.parse_args(args) - assert (args.fraction >= 0) and (args.fraction <= 1) - - train_fd = open(args.outputs[0], "w") - dev_fd = open(args.outputs[1], "w") - train_ctr = 0 - dev_ctr = 0 - random.seed(args.seed) - for line in open(args.input, "r"): - if random.random() <= args.fraction: - train_fd.write(line) - train_ctr += 1 - else: - dev_fd.write(line) - dev_ctr += 1 - total_ex = train_ctr + dev_ctr - log.info(f"Read {total_ex} examples from {args.input}") - train_frac = train_ctr / total_ex - log.info(f"Train: {train_ctr} examples ({train_frac:.02%})") - dev_frac = dev_ctr / total_ex - log.info(f"Dev: {dev_ctr} examples ({dev_frac:.02%})") - - -if __name__ == "__main__": - main(sys.argv[1:]) - sys.exit(0) diff --git a/probing/edge_data_stats.py b/probing/edge_data_stats.py deleted file mode 100755 index 8782a52d0..000000000 --- a/probing/edge_data_stats.py +++ /dev/null @@ -1,54 +0,0 @@ -#!/usr/bin/env python - -# Helper script to get stats on edge-probing data. -# -# Usage: -# python edge_data_stats.py -i /path/to/edge/probing/data/*.json -o stats.tsv -# -# Will print dataset size, num targets, etc. to stdout, and optionally write -# stats to a TSV file if -o is given. - -import argparse -import collections -import json -import logging as log -import os -import sys - -import pandas as pd -from tqdm import tqdm - -from data import utils - -log.basicConfig(format="%(asctime)s: %(message)s", datefmt="%m/%d %I:%M:%S %p", level=log.INFO) - - -def analyze_file(fname: str): - pd.options.display.float_format = "{:.2f}".format - log.info("Analyzing file: %s", fname) - record_iter = utils.load_json_data(fname) - stats = utils.EdgeProbingDatasetStats() - stats.compute(record_iter) - log.info(stats.format(_name=fname)) - return stats.to_series(_name=fname) - - -def main(args): - parser = argparse.ArgumentParser() - parser.add_argument("-o", dest="output", type=str, default="", help="Output file (TSV).") - parser.add_argument("-i", dest="inputs", type=str, nargs="+", help="Input files.") - args = parser.parse_args(args) - - all_stats = [] - for fname in args.inputs: - all_stats.append(analyze_file(fname)) - df = pd.DataFrame(all_stats) - df.set_index("_name", inplace=True) - if args.output: - log.info("Writing stats table to %s", args.output) - df.to_csv(args.output, sep="\t") - - -if __name__ == "__main__": - main(sys.argv[1:]) - sys.exit(0) diff --git a/probing/edgeprobe_data_viewer.ipynb b/probing/edgeprobe_data_viewer.ipynb deleted file mode 100644 index 2d6dfba45..000000000 --- a/probing/edgeprobe_data_viewer.ipynb +++ /dev/null @@ -1,190 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Edge Probing Data Viewer" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "import sys, os, re, json, io\n", - "import itertools\n", - "import collections\n", - "from importlib import reload\n", - "import pandas as pd\n", - "import numpy as np\n", - "from sklearn import metrics\n", - "from tqdm import tqdm\n", - "\n", - "from src.utils import utils" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "from IPython.display import display\n", - "import ipywidgets as widgets\n", - "\n", - "class EdgeProbingExample(object):\n", - " \n", - " def __init__(self, record):\n", - " self._data = record\n", - " \n", - " def __str__(self):\n", - " buf = io.StringIO()\n", - " text = self._data['text']\n", - " tokens = text.split()\n", - " buf.write(\"Text ({:d}): {:s}\\n\".format(len(tokens), text))\n", - " _fmt_span = lambda s,e: '[{:d},{:d})\\t\"{:s}\"'.format(s, e, \" \".join(tokens[s:e]))\n", - " for t in self._data['targets']:\n", - " buf.write(\"\\n\")\n", - " buf.write(\" span1: {}\\n\".format(_fmt_span(*t['span1'])))\n", - " if 'span2' in t:\n", - " buf.write(\" span2: {}\\n\".format(_fmt_span(*t['span2'])))\n", - " labels = utils.wrap_singleton_string(t['label'])\n", - " buf.write(\" label: ({:d})\\t {}\\n\".format(len(labels), \", \".join(labels)))\n", - " return buf.getvalue()\n", - " \n", - " def __repr__(self):\n", - " return str(self)" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['dep_ewt',\n", - " 'dpr',\n", - " 'ner_conll2003',\n", - " 'ontonotes-coref',\n", - " 'ontonotes-coref-conll',\n", - " 'ontonotes-ner',\n", - " 'spr2',\n", - " 'srl_conll2005',\n", - " 'srl_conll2012',\n", - " 'spr1',\n", - " 'stats.retokenized.OpenAI.BPE.tsv',\n", - " 'ih2',\n", - " 'ontonotes-constituents-old',\n", - " 'ontonotes-constituents']" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "edges_data_path = \"/nfs/jsalt/share/glue_data/edges\"\n", - "os.listdir(edges_data_path)" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\n", - "0it [00:00, ?it/s]\u001b[A\n", - "10732it [00:00, 63457.25it/s]\u001b[A\n", - "15680it [00:00, 71487.78it/s]\u001b[A" - ] - } - ], - "source": [ - "# record_file = \"/nfs/jsalt/share/glue_data/edges/spr1/spr1.dev.json.retokenized.bert-base-uncased\"\n", - "record_file = \"/nfs/jsalt/share/glue_data/edges/ontonotes-ner/ner_ontonotes_en_dev.json.retokenized.bert-base-cased\"\n", - "# record_file = \"/nfs/jsalt/home/nkim/edges/srl_conll2005/test.wsj.edges.real.json.notretokenized\"\n", - "# record_file = \"/nfs/jsalt/share/glue_data/edges/srl_conll2005/test.wsj.edges.json\"\n", - "# record_file = \"/nfs/jsalt/home/iftenney/spr2_test/dev.edges.json\"\n", - "# record_file = \"/nfs/jsalt/home/iftenney/spr2_test/dev.edges.json.retokenized.OpenAI.BPE\"\n", - "records = list(tqdm(utils.load_json_data(record_file)))\n", - "records = records[-1000:]\n", - "\n", - "all_texts = [r['text'] for r in records]" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "08437059cac1479dbf89c259dd42817f", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "interactive(children=(Dropdown(description='i', options={'In a stark contrast , the bench ##mark 30 - year Tre…" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 15, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "def print_info(i):\n", - " print(EdgeProbingExample(records[i]))\n", - "\n", - "widgets.interact(print_info, i={t:i for i,t in enumerate(all_texts[:1000])})" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.6.8" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/probing/edgeprobe_preds_sandbox.ipynb b/probing/edgeprobe_preds_sandbox.ipynb deleted file mode 100644 index 9e08adf13..000000000 --- a/probing/edgeprobe_preds_sandbox.ipynb +++ /dev/null @@ -1,967 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Edge Probing Predictions Sandbox\n", - "\n", - "Use this notebook as a starting point for #datascience on Edge Probing predictions. The code below (from `probing/analysis.py`) will load predictions from a run, do some pre-processing for convenience, and expose two DataFrames for analysis.\n", - "\n", - "We load the data into Pandas so it's easier to filter by various fields, and to select particular columns of interest (such as `labels.khot` and `preds.proba` for computing metrics). For an introduction to Pandas, see here: https://pandas.pydata.org/pandas-docs/stable/10min.html " - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "import sys, os, re, json\n", - "import itertools\n", - "import collections\n", - "from importlib import reload\n", - "import pandas as pd\n", - "import numpy as np\n", - "from sklearn import metrics" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The latest runs are here:" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[0m\u001b[01;34mcove-edges-constituent-ontonotes\u001b[0m/\r\n", - "\u001b[01;34mcove-edges-coref-ontonotes-conll\u001b[0m/\r\n", - "\u001b[01;34mcove-edges-dep-labeling-ewt\u001b[0m/\r\n", - "\u001b[01;34mcove-edges-dpr\u001b[0m/\r\n", - "\u001b[01;34mcove-edges-ner-ontonotes\u001b[0m/\r\n", - "\u001b[01;34mcove-edges-spr1\u001b[0m/\r\n", - "\u001b[01;34mcove-edges-spr2\u001b[0m/\r\n", - "\u001b[01;34mcove-edges-srl-conll2012\u001b[0m/\r\n", - "\u001b[01;34melmo-chars-edges-constituent-ontonotes\u001b[0m/\r\n", - "\u001b[01;34melmo-chars-edges-coref-ontonotes-conll\u001b[0m/\r\n", - "\u001b[01;34melmo-chars-edges-dep-labeling-ewt\u001b[0m/\r\n", - "\u001b[01;34melmo-chars-edges-dpr\u001b[0m/\r\n", - "\u001b[01;34melmo-chars-edges-ner-ontonotes\u001b[0m/\r\n", - "\u001b[01;34melmo-chars-edges-spr1\u001b[0m/\r\n", - "\u001b[01;34melmo-chars-edges-spr2\u001b[0m/\r\n", - "\u001b[01;34melmo-chars-edges-srl-conll2012\u001b[0m/\r\n", - "\u001b[01;34melmo-full-edges-constituent-ontonotes\u001b[0m/\r\n", - "\u001b[01;34melmo-full-edges-coref-ontonotes-conll\u001b[0m/\r\n", - "\u001b[01;34melmo-full-edges-dep-labeling-ewt\u001b[0m/\r\n", - "\u001b[01;34melmo-full-edges-dpr\u001b[0m/\r\n", - "\u001b[01;34melmo-full-edges-ner-ontonotes\u001b[0m/\r\n", - "\u001b[01;34melmo-full-edges-spr1\u001b[0m/\r\n", - "\u001b[01;34melmo-full-edges-spr2\u001b[0m/\r\n", - "\u001b[01;34melmo-full-edges-srl-conll2012\u001b[0m/\r\n", - "\u001b[01;34melmo-ortho-edges-constituent-ontonotes\u001b[0m/\r\n", - "\u001b[01;34melmo-ortho-edges-coref-ontonotes-conll\u001b[0m/\r\n", - "\u001b[01;34melmo-ortho-edges-dep-labeling-ewt\u001b[0m/\r\n", - "\u001b[01;34melmo-ortho-edges-dpr\u001b[0m/\r\n", - "\u001b[01;34melmo-ortho-edges-ner-ontonotes\u001b[0m/\r\n", - "\u001b[01;34melmo-ortho-edges-spr1\u001b[0m/\r\n", - "\u001b[01;34melmo-ortho-edges-spr2\u001b[0m/\r\n", - "\u001b[01;34melmo-ortho-edges-srl-conll2012\u001b[0m/\r\n", - "\u001b[01;34mfailed\u001b[0m/\r\n", - "\u001b[01;34mglove-edges-constituent-ontonotes\u001b[0m/\r\n", - "\u001b[01;34mglove-edges-coref-ontonotes-conll\u001b[0m/\r\n", - "\u001b[01;34mglove-edges-dep-labeling-ewt\u001b[0m/\r\n", - "\u001b[01;34mglove-edges-dpr\u001b[0m/\r\n", - "\u001b[01;34mglove-edges-ner-ontonotes\u001b[0m/\r\n", - "\u001b[01;34mglove-edges-spr1\u001b[0m/\r\n", - "\u001b[01;34mglove-edges-spr2\u001b[0m/\r\n", - "\u001b[01;34mglove-edges-srl-conll2012\u001b[0m/\r\n", - "\u001b[01;34mopenai-edges-constituent-ontonotes\u001b[0m/\r\n", - "\u001b[01;34mopenai-edges-coref-ontonotes-conll\u001b[0m/\r\n", - "\u001b[01;34mopenai-edges-dep-labeling-ewt\u001b[0m/\r\n", - "\u001b[01;34mopenai-edges-dpr\u001b[0m/\r\n", - "\u001b[01;34mopenai-edges-ner-ontonotes\u001b[0m/\r\n", - "\u001b[01;34mopenai-edges-spr1\u001b[0m/\r\n", - "\u001b[01;34mopenai-edges-spr2\u001b[0m/\r\n", - "\u001b[01;34mopenai-edges-srl-conll2012\u001b[0m/\r\n", - "scores.tsv\r\n" - ] - } - ], - "source": [ - "ls /nfs/jsalt/home/iftenney/exp/edges-20180913/" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The `elmo-chars` experiments probe the char CNN layer only (lexical baseline), while the `elmo-full` models use full ELMo with learned mixing weights. The run dir for each is just called \"run\" by default. " - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Number of examples: 276\n", - "Number of total targets: 582\n", - "Labels (20 total):\n", - "['awareness', 'change_of_location', 'change_of_possession', 'change_of_state', 'change_of_state_continuous', 'changes_possession', 'existed_after', 'existed_before', 'existed_during', 'exists_as_physical', 'instigation', 'location_of_event', 'makes_physical_contact', 'partitive', 'predicate_changed_argument', 'sentient', 'stationary', 'volition', 'was_for_benefit', 'was_used']\n" - ] - } - ], - "source": [ - "import analysis\n", - "reload(analysis)\n", - "\n", - "run_dir = \"/nfs/jsalt/home/iftenney/exp/edges-20180913/elmo-full-edges-spr2/run\"\n", - "preds = analysis.Predictions.from_run(run_dir, 'edges-spr2', 'test')\n", - "print(\"Number of examples: %d\" % len(preds.example_df))\n", - "print(\"Number of total targets: %d\" % len(preds.target_df))\n", - "print(\"Labels (%d total):\" % len(preds.all_labels))\n", - "print(preds.all_labels)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Top-level example info\n", - "\n", - "`preds.example_df` contains information on the top-level examples. Mostly, this just stores the input text and any metadata fields that were present in the original data. This is useful if you want to link the targets back to the text, but you shouldn't need it to compute most metrics." - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
idxinfo.grammaticalinfo.sent-idinfo.sent_idinfo.sourceinfo.splittext
idx
005.010081008SPR2testIn a timid voice , he says : &quot; If an airp...
115.010091009SPR2test&quot; Wonderful ! &quot; Winston beams .
225.010171017SPR2test&quot; Our new lunar transportation system uti...
332.010231023SPR2testThey want to use LTS to tie into NASA &apos; s...
445.010241024SPR2test&quot; We are so excited that the White House ...
\n", - "
" - ], - "text/plain": [ - " idx info.grammatical info.sent-id info.sent_id info.source info.split \\\n", - "idx \n", - "0 0 5.0 1008 1008 SPR2 test \n", - "1 1 5.0 1009 1009 SPR2 test \n", - "2 2 5.0 1017 1017 SPR2 test \n", - "3 3 2.0 1023 1023 SPR2 test \n", - "4 4 5.0 1024 1024 SPR2 test \n", - "\n", - " text \n", - "idx \n", - "0 In a timid voice , he says : " If an airp... \n", - "1 " Wonderful ! " Winston beams . \n", - "2 " Our new lunar transportation system uti... \n", - "3 They want to use LTS to tie into NASA ' s... \n", - "4 " We are so excited that the White House ... " - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "preds.example_df.head()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Target info and predictions\n", - "\n", - "`preds.target_df` contains the per-target input fields (`span1`, `span2`, and `label`) as well as any metadata associated with individual targets. The `idx` column references a row in `example_df` that this target belongs to, if you need to recover the original text.\n", - "\n", - "The loader code does some preprocessing for convenience. In particular, we add a `label.ids` column which maps the list-of-string `label` column into a list of integer ids for these targets, as well as `label.khot` which contains a K-hot encoding of these ids. \n", - "\n", - "Each entry in `label.khot` should align to the corresponding entry in `preds.proba`, which contains the model's predicted probabilities $\\hat{y} \\in [0,1]$ for each class.\n", - "\n", - "For specific analysis, it might be easier to work with the wide and long forms of this DataFrame - see cells below." - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
idxinfo.is_pilotinfo.pred_lemmainfo.span1_textinfo.span2_txtlabelpreds.probaspan1span2label.idslabel.khot
00Falsesaysayshe[awareness, existed_after, existed_before, exi...[0.9507238268852234, 0.08021300286054611, 0.00...(6, 7)(5, 6)[0, 6, 7, 8, 10, 15, 17, 19][1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, ...
10Falsecarrycarryingwinston peters[awareness, change_of_location, change_of_stat...[0.8147344589233398, 0.8972967863082886, 0.146...(12, 13)(13, 15)[0, 1, 4, 6, 7, 8, 10, 15, 17, 18, 19][1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, ...
20Falseblowblownan airplane carrying winston peters[change_of_location, change_of_state, existed_...[0.20997169613838196, 0.7638567686080933, 0.11...(16, 17)(10, 15)[1, 3, 7, 8][0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, ...
31Falsebeambeamswinston[awareness, change_of_state_continuous, existe...[0.5660699605941772, 0.15035615861415863, 0.03...(5, 6)(4, 5)[0, 4, 6, 7, 8, 10, 13, 15, 17, 18, 19][1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, ...
42Falsetelltoldkistler[awareness, existed_after, existed_before, exi...[0.9896626472473145, 0.022328440099954605, 0.0...(30, 31)(29, 30)[0, 6, 7, 8, 10, 15, 17, 19][1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, ...
\n", - "
" - ], - "text/plain": [ - " idx info.is_pilot info.pred_lemma info.span1_text \\\n", - "0 0 False say says \n", - "1 0 False carry carrying \n", - "2 0 False blow blown \n", - "3 1 False beam beams \n", - "4 2 False tell told \n", - "\n", - " info.span2_txt \\\n", - "0 he \n", - "1 winston peters \n", - "2 an airplane carrying winston peters \n", - "3 winston \n", - "4 kistler \n", - "\n", - " label \\\n", - "0 [awareness, existed_after, existed_before, exi... \n", - "1 [awareness, change_of_location, change_of_stat... \n", - "2 [change_of_location, change_of_state, existed_... \n", - "3 [awareness, change_of_state_continuous, existe... \n", - "4 [awareness, existed_after, existed_before, exi... \n", - "\n", - " preds.proba span1 span2 \\\n", - "0 [0.9507238268852234, 0.08021300286054611, 0.00... (6, 7) (5, 6) \n", - "1 [0.8147344589233398, 0.8972967863082886, 0.146... (12, 13) (13, 15) \n", - "2 [0.20997169613838196, 0.7638567686080933, 0.11... (16, 17) (10, 15) \n", - "3 [0.5660699605941772, 0.15035615861415863, 0.03... (5, 6) (4, 5) \n", - "4 [0.9896626472473145, 0.022328440099954605, 0.0... (30, 31) (29, 30) \n", - "\n", - " label.ids \\\n", - "0 [0, 6, 7, 8, 10, 15, 17, 19] \n", - "1 [0, 1, 4, 6, 7, 8, 10, 15, 17, 18, 19] \n", - "2 [1, 3, 7, 8] \n", - "3 [0, 4, 6, 7, 8, 10, 13, 15, 17, 18, 19] \n", - "4 [0, 6, 7, 8, 10, 15, 17, 19] \n", - "\n", - " label.khot \n", - "0 [1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, ... \n", - "1 [1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, ... \n", - "2 [0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, ... \n", - "3 [1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, ... \n", - "4 [1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, ... " - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "preds.target_df.head()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Wide and Long Data\n", - "\n", - "For background on these views, see https://altair-viz.github.io/user_guide/data.html#long-form-vs-wide-form-data\n", - "\n", - "Here's a \"wide\" version of the data, with the usual metadata plus `2* num_labels` columns: `label.true.` and `preds.proba.` for each target class." - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
idxinfo.is_pilotinfo.pred_lemmainfo.span1_textinfo.span2_txtspan1span2label.true.awarenesslabel.true.change_of_locationlabel.true.change_of_possession...preds.proba.instigationpreds.proba.location_of_eventpreds.proba.makes_physical_contactpreds.proba.partitivepreds.proba.predicate_changed_argumentpreds.proba.sentientpreds.proba.stationarypreds.proba.volitionpreds.proba.was_for_benefitpreds.proba.was_used
00Falsesaysayshe(6, 7)(5, 6)100...0.9368600.0044010.0032610.2542280.0028050.9757600.0037330.9389580.1431980.945751
10Falsecarrycarryingwinston peters(12, 13)(13, 15)110...0.7423840.0069770.0062860.0789800.0065070.6672340.0049350.6524890.3875250.932438
20Falseblowblownan airplane carrying winston peters(16, 17)(10, 15)010...0.1734880.0091590.0139240.2773870.0044500.1941290.0041150.0292750.1241220.724787
31Falsebeambeamswinston(5, 6)(4, 5)100...0.9184810.0095430.0075550.1203180.0078200.8081030.0074160.5787320.5447440.919867
42Falsetelltoldkistler(30, 31)(29, 30)100...0.9224900.0157240.0119150.3147000.0099690.9630260.0097970.9853730.7491020.960411
\n", - "

5 rows × 47 columns

\n", - "
" - ], - "text/plain": [ - " idx info.is_pilot info.pred_lemma info.span1_text \\\n", - "0 0 False say says \n", - "1 0 False carry carrying \n", - "2 0 False blow blown \n", - "3 1 False beam beams \n", - "4 2 False tell told \n", - "\n", - " info.span2_txt span1 span2 \\\n", - "0 he (6, 7) (5, 6) \n", - "1 winston peters (12, 13) (13, 15) \n", - "2 an airplane carrying winston peters (16, 17) (10, 15) \n", - "3 winston (5, 6) (4, 5) \n", - "4 kistler (30, 31) (29, 30) \n", - "\n", - " label.true.awareness label.true.change_of_location \\\n", - "0 1 0 \n", - "1 1 1 \n", - "2 0 1 \n", - "3 1 0 \n", - "4 1 0 \n", - "\n", - " label.true.change_of_possession ... \\\n", - "0 0 ... \n", - "1 0 ... \n", - "2 0 ... \n", - "3 0 ... \n", - "4 0 ... \n", - "\n", - " preds.proba.instigation preds.proba.location_of_event \\\n", - "0 0.936860 0.004401 \n", - "1 0.742384 0.006977 \n", - "2 0.173488 0.009159 \n", - "3 0.918481 0.009543 \n", - "4 0.922490 0.015724 \n", - "\n", - " preds.proba.makes_physical_contact preds.proba.partitive \\\n", - "0 0.003261 0.254228 \n", - "1 0.006286 0.078980 \n", - "2 0.013924 0.277387 \n", - "3 0.007555 0.120318 \n", - "4 0.011915 0.314700 \n", - "\n", - " preds.proba.predicate_changed_argument preds.proba.sentient \\\n", - "0 0.002805 0.975760 \n", - "1 0.006507 0.667234 \n", - "2 0.004450 0.194129 \n", - "3 0.007820 0.808103 \n", - "4 0.009969 0.963026 \n", - "\n", - " preds.proba.stationary preds.proba.volition preds.proba.was_for_benefit \\\n", - "0 0.003733 0.938958 0.143198 \n", - "1 0.004935 0.652489 0.387525 \n", - "2 0.004115 0.029275 0.124122 \n", - "3 0.007416 0.578732 0.544744 \n", - "4 0.009797 0.985373 0.749102 \n", - "\n", - " preds.proba.was_used \n", - "0 0.945751 \n", - "1 0.932438 \n", - "2 0.724787 \n", - "3 0.919867 \n", - "4 0.960411 \n", - "\n", - "[5 rows x 47 columns]" - ] - }, - "execution_count": 14, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "preds.target_df_wide.head()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We can fairly easily compute per-label metrics from the wide form, by selecting the appropriate pair of columns:" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "awareness 0.897436\n", - "change_of_location 0.251969\n", - "change_of_possession 0.048780\n", - "change_of_state 0.387097\n", - "change_of_state_continuous 0.595890\n", - "changes_possession 0.000000\n", - "existed_after 0.951686\n", - "existed_before 0.919081\n", - "existed_during 0.987826\n", - "exists_as_physical 0.000000\n", - "instigation 0.806565\n", - "location_of_event 0.000000\n", - "makes_physical_contact 0.000000\n", - "partitive 0.055944\n", - "predicate_changed_argument 0.000000\n", - "sentient 0.888519\n", - "stationary 0.000000\n", - "volition 0.845735\n", - "was_for_benefit 0.640316\n", - "was_used 0.917910\n", - "dtype: float64\n", - "Macro average F1: 0.4597\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/usr/share/anaconda3/lib/python3.6/site-packages/sklearn/metrics/classification.py:1135: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 due to no predicted samples.\n", - " 'precision', 'predicted', average, warn_for)\n" - ] - } - ], - "source": [ - "wide_df = preds.target_df_wide\n", - "scores_by_label = {}\n", - "for label in preds.all_labels:\n", - " y_true = wide_df['label.true.' + label]\n", - " y_pred = wide_df['preds.proba.' + label] >= 0.5\n", - " score = metrics.f1_score(y_true=y_true, y_pred=y_pred)\n", - " scores_by_label[label] = score\n", - "scores = pd.Series(scores_by_label)\n", - "print(scores)\n", - "print(\"Macro average F1: %.04f\" % scores.mean())" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "And here's a \"long\" version of the same, with a single `label` column, and one column each for `label.true` and `preds.proba` for that label:" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
idxlabellabel.truepreds.proba
00awareness10.950724
10change_of_location00.080213
20change_of_possession00.007079
30change_of_state00.093276
40change_of_state_continuous00.160939
\n", - "
" - ], - "text/plain": [ - " idx label label.true preds.proba\n", - "0 0 awareness 1 0.950724\n", - "1 0 change_of_location 0 0.080213\n", - "2 0 change_of_possession 0 0.007079\n", - "3 0 change_of_state 0 0.093276\n", - "4 0 change_of_state_continuous 0 0.160939" - ] - }, - "execution_count": 16, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "preds.target_df_long.head()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We can easily get the set of labels available here:" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array(['awareness', 'change_of_location', 'change_of_possession',\n", - " 'change_of_state', 'change_of_state_continuous',\n", - " 'changes_possession', 'existed_after', 'existed_before',\n", - " 'existed_during', 'exists_as_physical', 'instigation',\n", - " 'location_of_event', 'makes_physical_contact', 'partitive',\n", - " 'predicate_changed_argument', 'sentient', 'stationary', 'volition',\n", - " 'was_for_benefit', 'was_used'], dtype=object)" - ] - }, - "execution_count": 17, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "preds.target_df_long.label.unique()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "And easily compute micro-averaged metrics by simply comparing the `label.true` and `preds.proba` columns:" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0.8297897060532125" - ] - }, - "execution_count": 18, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "from sklearn import metrics\n", - "long_df = preds.target_df_long\n", - "metrics.f1_score(y_true=long_df['label.true'], y_pred=(long_df['preds.proba'] >= 0.5))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.6.5" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/probing/edgeprobe_single_sentence_comparisons.ipynb b/probing/edgeprobe_single_sentence_comparisons.ipynb deleted file mode 100644 index 410ba1f93..000000000 --- a/probing/edgeprobe_single_sentence_comparisons.ipynb +++ /dev/null @@ -1,2134 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Edge Probing Side-by-Side Examples\n", - "\n", - "This notebook is designed to load predictions from two runs and mine for interesting win or loss examples." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import sys, os, re, json\n", - "from importlib import reload\n", - "\n", - "from src.utils import utils" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from tqdm import tqdm\n", - "import pandas as pd\n", - "import numpy as np" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "import analysis; reload(analysis)" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [], - "source": [ - "def load_raw_preds(task_name, exp_type, split_name=\"val\"):\n", - " preds_path = f\"{project_dir}/{exp_type}-{task_name}/run/{task_name}_{split_name}.json\"\n", - " return list(utils.load_json_data(preds_path))\n", - "\n", - "def load_task_preds(task_name, exp_type, split_name=\"val\"):\n", - " run_dir = f\"{project_dir}/{exp_type}-{task_name}/run\"\n", - " return analysis.Predictions.from_run(run_dir, task_name, split_name)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Use the cell below to configure what to load:\n", - "\n", - "- `project_dir` should be the path to a directory of experiments\n", - "- `exp_types` should be the two experiment types to compare\n", - "- `task_name` is the task to look at\n", - "- `split_name` is the split (`val` or `test`) to look at\n", - "\n", - "At minimum, you'll want to point `project_dir` to something available on your system.\n", - "\n", - "This assumes that the project directory contains experiments named as `{exp_type}-{task_name}`, each containing a single run named `run`." - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [], - "source": [ - "# project_dir = \"/nfs/jsalt/exp/edges-20180926-elmofix\"\n", - "# exp_types = [\"elmo-chars\", \"elmo-full\"]\n", - "# project_dir = \"/nfs/jsalt/exp/edges-20190124-bert\"\n", - "# exp_types = [\"bert-base-uncased-lex\", \"bert-base-uncased-cat\"]\n", - "project_dir = \"/nfs/jsalt/home/iftenney/exp/bert_mix_20190129\"\n", - "exp_types = [\"bert-large-uncased-lex\", \"bert-large-uncased-mix\"]\n", - "\n", - "# task_name = \"edges-srl-conll2012\"\n", - "# task_name = \"edges-spr2\"\n", - "task_name = \"edges-coref-ontonotes-conll\"\n", - "split_name = \"val\" # look at development / validation sets" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We'll load both the raw predictions (records loaded from JSON), and also process them (with `load_task_preds`, which uses `analysis.Predictions`) into a long-form DataFrame. We can use the DataFrame to easily score groups of targets, and then retrieve the full records from the raw predictions based on the example index." - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [], - "source": [ - "r0 = load_raw_preds(task_name, exp_types[0])\n", - "r1 = load_raw_preds(task_name, exp_types[1])" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "02/09/2019 02:25:52 - INFO - root - Loading vocabulary from /nfs/jsalt/home/iftenney/exp/bert_mix_20190129/bert-large-uncased-lex-edges-coref-ontonotes-conll/vocab\n", - "02/09/2019 02:25:52 - INFO - allennlp.data.vocabulary - Loading token dictionary from /nfs/jsalt/home/iftenney/exp/bert_mix_20190129/bert-large-uncased-lex-edges-coref-ontonotes-conll/vocab.\n", - "02/09/2019 02:25:52 - INFO - root - Loading predictions from /nfs/jsalt/home/iftenney/exp/bert_mix_20190129/bert-large-uncased-lex-edges-coref-ontonotes-conll/run/edges-coref-ontonotes-conll_val.json\n", - "02/09/2019 02:25:53 - INFO - root - Loading vocabulary from /nfs/jsalt/home/iftenney/exp/bert_mix_20190129/bert-large-uncased-mix-edges-coref-ontonotes-conll/vocab\n", - "02/09/2019 02:25:53 - INFO - allennlp.data.vocabulary - Loading token dictionary from /nfs/jsalt/home/iftenney/exp/bert_mix_20190129/bert-large-uncased-mix-edges-coref-ontonotes-conll/vocab.\n", - "02/09/2019 02:25:53 - INFO - root - Loading predictions from /nfs/jsalt/home/iftenney/exp/bert_mix_20190129/bert-large-uncased-mix-edges-coref-ontonotes-conll/run/edges-coref-ontonotes-conll_val.json\n" - ] - } - ], - "source": [ - "p0 = load_task_preds(task_name, exp_types[0])\n", - "p1 = load_task_preds(task_name, exp_types[1])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The cell below will score the predictions; this might take a couple minutes to run on larger datasets." - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": { - "scrolled": true - }, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "02/09/2019 02:25:54 - INFO - root - Generating long-form target DataFrame. May be slow... \n", - "02/09/2019 02:25:54 - INFO - root - span2 detected; adding span_distance to long-form DataFrame.\n", - "02/09/2019 02:25:54 - INFO - root - Done!\n", - "100%|██████████| 5044/5044 [00:07<00:00, 689.80it/s]\n", - "02/09/2019 02:26:01 - INFO - root - Generating long-form target DataFrame. May be slow... \n", - "02/09/2019 02:26:01 - INFO - root - span2 detected; adding span_distance to long-form DataFrame.\n", - "02/09/2019 02:26:01 - INFO - root - Done!\n", - "100%|██████████| 5044/5044 [00:07<00:00, 695.68it/s]\n" - ] - } - ], - "source": [ - "def score_by_example(df):\n", - " # Score targets, but grouped on example index\n", - " gb = df.groupby(by='ex_idx')\n", - " records = []\n", - " for key, idxs in tqdm(gb.groups.items()):\n", - " sub_df = df.loc[idxs]\n", - " record = analysis.Predictions.score_long_df(sub_df)\n", - " record['ex_idx'] = key\n", - " records.append(record)\n", - " score_df = pd.DataFrame.from_records(records)\n", - "\n", - " score_df['precision'] = analysis.get_precision(score_df).fillna(value=1.0)\n", - " score_df['recall'] = analysis.get_recall(score_df).fillna(value=1.0)\n", - " score_df['f1'] = analysis.get_f1(score_df).fillna(value=0.0)\n", - " \n", - " return score_df\n", - "\n", - "s0 = score_by_example(p0.target_df_long)\n", - "s1 = score_by_example(p1.target_df_long)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Find examples with a large gain from base -> expt\n", - "\n", - "We'll group targets by the input example (`ex_idx`) and look at the scores across the whole example. Each of the cells below should print a filtered set of example indices that might be worth looking at.\n", - "\n", - "`mdf` merges the per-example scores from base and expt runs (i.e. `exp_types[0]` and `exp_types[1]`) so we can look for sentences where, for example, the lexical model does poorly but the full-context model gets most of the targets right." - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [], - "source": [ - "mdf = pd.merge(s0, s1, how='inner', on='ex_idx', suffixes=(\"_base\", \"_expt\"))\n", - "\n", - "mdf['f1_delta'] = mdf[\"f1_expt\"] - mdf[\"f1_base\"]\n", - "mdf['abs_f1_delta'] = mdf['f1_delta'].map(np.abs)" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
ex_idxfn_count_basefp_count_basetn_count_basetp_count_baseprecision_baserecall_basef1_basefn_count_exptfp_count_expttn_count_expttp_count_exptprecision_exptrecall_exptf1_exptf1_deltaabs_f1_delta
1485148533000.0000000.0000000.00000000331.001.01.0000001.0000001.000000
2496249633000.0000000.0000000.00000000331.001.01.0000001.0000001.000000
4167416733000.0000000.0000000.00000000331.001.01.0000001.0000001.000000
2298229833000.0000000.0000000.00000000331.001.01.0000001.0000001.000000
65865833000.0000000.0000000.00000000331.001.01.0000001.0000001.000000
1302130266000.0000000.0000000.00000000661.001.01.0000001.0000001.000000
3862386233000.0000000.0000000.00000001230.751.00.8571430.8571430.857143
4570457055110.1666670.1666670.16666700661.001.01.0000000.8333330.833333
85485422110.3333330.3333330.33333300331.001.01.0000000.6666670.666667
2308230822110.3333330.3333330.33333300331.001.01.0000000.6666670.666667
\n", - "
" - ], - "text/plain": [ - " ex_idx fn_count_base fp_count_base tn_count_base tp_count_base \\\n", - "1485 1485 3 3 0 0 \n", - "2496 2496 3 3 0 0 \n", - "4167 4167 3 3 0 0 \n", - "2298 2298 3 3 0 0 \n", - "658 658 3 3 0 0 \n", - "1302 1302 6 6 0 0 \n", - "3862 3862 3 3 0 0 \n", - "4570 4570 5 5 1 1 \n", - "854 854 2 2 1 1 \n", - "2308 2308 2 2 1 1 \n", - "\n", - " precision_base recall_base f1_base fn_count_expt fp_count_expt \\\n", - "1485 0.000000 0.000000 0.000000 0 0 \n", - "2496 0.000000 0.000000 0.000000 0 0 \n", - "4167 0.000000 0.000000 0.000000 0 0 \n", - "2298 0.000000 0.000000 0.000000 0 0 \n", - "658 0.000000 0.000000 0.000000 0 0 \n", - "1302 0.000000 0.000000 0.000000 0 0 \n", - "3862 0.000000 0.000000 0.000000 0 1 \n", - "4570 0.166667 0.166667 0.166667 0 0 \n", - "854 0.333333 0.333333 0.333333 0 0 \n", - "2308 0.333333 0.333333 0.333333 0 0 \n", - "\n", - " tn_count_expt tp_count_expt precision_expt recall_expt f1_expt \\\n", - "1485 3 3 1.00 1.0 1.000000 \n", - "2496 3 3 1.00 1.0 1.000000 \n", - "4167 3 3 1.00 1.0 1.000000 \n", - "2298 3 3 1.00 1.0 1.000000 \n", - "658 3 3 1.00 1.0 1.000000 \n", - "1302 6 6 1.00 1.0 1.000000 \n", - "3862 2 3 0.75 1.0 0.857143 \n", - "4570 6 6 1.00 1.0 1.000000 \n", - "854 3 3 1.00 1.0 1.000000 \n", - "2308 3 3 1.00 1.0 1.000000 \n", - "\n", - " f1_delta abs_f1_delta \n", - "1485 1.000000 1.000000 \n", - "2496 1.000000 1.000000 \n", - "4167 1.000000 1.000000 \n", - "2298 1.000000 1.000000 \n", - "658 1.000000 1.000000 \n", - "1302 1.000000 1.000000 \n", - "3862 0.857143 0.857143 \n", - "4570 0.833333 0.833333 \n", - "854 0.666667 0.666667 \n", - "2308 0.666667 0.666667 " - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Find examples with more targets\n", - "mdf[mdf['tp_count_expt'] >= 3].sort_values(by=\"f1_delta\", ascending=False).head(10)" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/usr/share/anaconda3/lib/python3.6/site-packages/ipykernel_launcher.py:5: FutureWarning: 'idx' is both an index level and a column label.\n", - "Defaulting to column, but this will raise an ambiguity error in a future version\n", - " \"\"\"\n" - ] - }, - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
ex_idxfn_count_basefp_count_basetn_count_basetp_count_baseprecision_baserecall_basef1_basefn_count_exptfp_count_expttn_count_expttp_count_exptprecision_exptrecall_exptf1_exptf1_deltaabs_f1_deltaidxnum_tokens
1485148533000.0000000.0000000.00000000331.01.01.01.0000001.000000148512
65865833000.0000000.0000000.00000000331.01.01.01.0000001.00000065814
1868186844220.3333330.3333330.33333300661.01.01.00.6666670.666667186814
2562256222110.3333330.3333330.33333300331.01.01.00.6666670.666667256214
2308230822110.3333330.3333330.33333300331.01.01.00.6666670.666667230811
2303230344220.3333330.3333330.33333300661.01.01.00.6666670.666667230314
1817181722110.3333330.3333330.33333300331.01.01.00.6666670.666667181710
2138213822110.3333330.3333330.33333300331.01.01.00.6666670.666667213813
2039203922110.3333330.3333330.33333300331.01.01.00.6666670.666667203913
1284128422110.3333330.3333330.33333300331.01.01.00.6666670.666667128413
16116122110.3333330.3333330.33333300331.01.01.00.6666670.6666671619
1907190733330.5000000.5000000.50000000661.01.01.00.5000000.500000190713
2112211233330.5000000.5000000.50000000661.01.01.00.5000000.500000211211
1564156411220.6666670.6666670.66666700331.01.01.00.3333330.333333156414
2468246811220.6666670.6666670.66666700331.01.01.00.3333330.33333324688
1712171211220.6666670.6666670.66666700331.01.01.00.3333330.33333317128
3204320411220.6666670.6666670.66666700331.01.01.00.3333330.333333320412
1717171711220.6666670.6666670.66666700331.01.01.00.3333330.333333171710
2400240011220.6666670.6666670.66666700331.01.01.00.3333330.33333324009
2383238311220.6666670.6666670.66666700331.01.01.00.3333330.333333238312
1640164011220.6666670.6666670.66666700331.01.01.00.3333330.333333164012
1664166411220.6666670.6666670.66666700331.01.01.00.3333330.333333166410
2377237711220.6666670.6666670.66666700331.01.01.00.3333330.333333237714
1553155311220.6666670.6666670.66666700331.01.01.00.3333330.333333155314
2382238211220.6666670.6666670.66666700331.01.01.00.3333330.333333238212
29429411220.6666670.6666670.66666700331.01.01.00.3333330.3333332947
2827282711220.6666670.6666670.66666700331.01.01.00.3333330.333333282713
2831283111220.6666670.6666670.66666700331.01.01.00.3333330.333333283114
2833283311220.6666670.6666670.66666700331.01.01.00.3333330.33333328339
1023102311220.6666670.6666670.66666700331.01.01.00.3333330.333333102310
\n", - "
" - ], - "text/plain": [ - " ex_idx fn_count_base fp_count_base tn_count_base tp_count_base \\\n", - "1485 1485 3 3 0 0 \n", - "658 658 3 3 0 0 \n", - "1868 1868 4 4 2 2 \n", - "2562 2562 2 2 1 1 \n", - "2308 2308 2 2 1 1 \n", - "2303 2303 4 4 2 2 \n", - "1817 1817 2 2 1 1 \n", - "2138 2138 2 2 1 1 \n", - "2039 2039 2 2 1 1 \n", - "1284 1284 2 2 1 1 \n", - "161 161 2 2 1 1 \n", - "1907 1907 3 3 3 3 \n", - "2112 2112 3 3 3 3 \n", - "1564 1564 1 1 2 2 \n", - "2468 2468 1 1 2 2 \n", - "1712 1712 1 1 2 2 \n", - "3204 3204 1 1 2 2 \n", - "1717 1717 1 1 2 2 \n", - "2400 2400 1 1 2 2 \n", - "2383 2383 1 1 2 2 \n", - "1640 1640 1 1 2 2 \n", - "1664 1664 1 1 2 2 \n", - "2377 2377 1 1 2 2 \n", - "1553 1553 1 1 2 2 \n", - "2382 2382 1 1 2 2 \n", - "294 294 1 1 2 2 \n", - "2827 2827 1 1 2 2 \n", - "2831 2831 1 1 2 2 \n", - "2833 2833 1 1 2 2 \n", - "1023 1023 1 1 2 2 \n", - "\n", - " precision_base recall_base f1_base fn_count_expt fp_count_expt \\\n", - "1485 0.000000 0.000000 0.000000 0 0 \n", - "658 0.000000 0.000000 0.000000 0 0 \n", - "1868 0.333333 0.333333 0.333333 0 0 \n", - "2562 0.333333 0.333333 0.333333 0 0 \n", - "2308 0.333333 0.333333 0.333333 0 0 \n", - "2303 0.333333 0.333333 0.333333 0 0 \n", - "1817 0.333333 0.333333 0.333333 0 0 \n", - "2138 0.333333 0.333333 0.333333 0 0 \n", - "2039 0.333333 0.333333 0.333333 0 0 \n", - "1284 0.333333 0.333333 0.333333 0 0 \n", - "161 0.333333 0.333333 0.333333 0 0 \n", - "1907 0.500000 0.500000 0.500000 0 0 \n", - "2112 0.500000 0.500000 0.500000 0 0 \n", - "1564 0.666667 0.666667 0.666667 0 0 \n", - "2468 0.666667 0.666667 0.666667 0 0 \n", - "1712 0.666667 0.666667 0.666667 0 0 \n", - "3204 0.666667 0.666667 0.666667 0 0 \n", - "1717 0.666667 0.666667 0.666667 0 0 \n", - "2400 0.666667 0.666667 0.666667 0 0 \n", - "2383 0.666667 0.666667 0.666667 0 0 \n", - "1640 0.666667 0.666667 0.666667 0 0 \n", - "1664 0.666667 0.666667 0.666667 0 0 \n", - "2377 0.666667 0.666667 0.666667 0 0 \n", - "1553 0.666667 0.666667 0.666667 0 0 \n", - "2382 0.666667 0.666667 0.666667 0 0 \n", - "294 0.666667 0.666667 0.666667 0 0 \n", - "2827 0.666667 0.666667 0.666667 0 0 \n", - "2831 0.666667 0.666667 0.666667 0 0 \n", - "2833 0.666667 0.666667 0.666667 0 0 \n", - "1023 0.666667 0.666667 0.666667 0 0 \n", - "\n", - " tn_count_expt tp_count_expt precision_expt recall_expt f1_expt \\\n", - "1485 3 3 1.0 1.0 1.0 \n", - "658 3 3 1.0 1.0 1.0 \n", - "1868 6 6 1.0 1.0 1.0 \n", - "2562 3 3 1.0 1.0 1.0 \n", - "2308 3 3 1.0 1.0 1.0 \n", - "2303 6 6 1.0 1.0 1.0 \n", - "1817 3 3 1.0 1.0 1.0 \n", - "2138 3 3 1.0 1.0 1.0 \n", - "2039 3 3 1.0 1.0 1.0 \n", - "1284 3 3 1.0 1.0 1.0 \n", - "161 3 3 1.0 1.0 1.0 \n", - "1907 6 6 1.0 1.0 1.0 \n", - "2112 6 6 1.0 1.0 1.0 \n", - "1564 3 3 1.0 1.0 1.0 \n", - "2468 3 3 1.0 1.0 1.0 \n", - "1712 3 3 1.0 1.0 1.0 \n", - "3204 3 3 1.0 1.0 1.0 \n", - "1717 3 3 1.0 1.0 1.0 \n", - "2400 3 3 1.0 1.0 1.0 \n", - "2383 3 3 1.0 1.0 1.0 \n", - "1640 3 3 1.0 1.0 1.0 \n", - "1664 3 3 1.0 1.0 1.0 \n", - "2377 3 3 1.0 1.0 1.0 \n", - "1553 3 3 1.0 1.0 1.0 \n", - "2382 3 3 1.0 1.0 1.0 \n", - "294 3 3 1.0 1.0 1.0 \n", - "2827 3 3 1.0 1.0 1.0 \n", - "2831 3 3 1.0 1.0 1.0 \n", - "2833 3 3 1.0 1.0 1.0 \n", - "1023 3 3 1.0 1.0 1.0 \n", - "\n", - " f1_delta abs_f1_delta idx num_tokens \n", - "1485 1.000000 1.000000 1485 12 \n", - "658 1.000000 1.000000 658 14 \n", - "1868 0.666667 0.666667 1868 14 \n", - "2562 0.666667 0.666667 2562 14 \n", - "2308 0.666667 0.666667 2308 11 \n", - "2303 0.666667 0.666667 2303 14 \n", - "1817 0.666667 0.666667 1817 10 \n", - "2138 0.666667 0.666667 2138 13 \n", - "2039 0.666667 0.666667 2039 13 \n", - "1284 0.666667 0.666667 1284 13 \n", - "161 0.666667 0.666667 161 9 \n", - "1907 0.500000 0.500000 1907 13 \n", - "2112 0.500000 0.500000 2112 11 \n", - "1564 0.333333 0.333333 1564 14 \n", - "2468 0.333333 0.333333 2468 8 \n", - "1712 0.333333 0.333333 1712 8 \n", - "3204 0.333333 0.333333 3204 12 \n", - "1717 0.333333 0.333333 1717 10 \n", - "2400 0.333333 0.333333 2400 9 \n", - "2383 0.333333 0.333333 2383 12 \n", - "1640 0.333333 0.333333 1640 12 \n", - "1664 0.333333 0.333333 1664 10 \n", - "2377 0.333333 0.333333 2377 14 \n", - "1553 0.333333 0.333333 1553 14 \n", - "2382 0.333333 0.333333 2382 12 \n", - "294 0.333333 0.333333 294 7 \n", - "2827 0.333333 0.333333 2827 13 \n", - "2831 0.333333 0.333333 2831 14 \n", - "2833 0.333333 0.333333 2833 9 \n", - "1023 0.333333 0.333333 1023 10 " - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Find examples with shorter sentences\n", - "edf = p0.example_df.copy()\n", - "edf['num_tokens'] = edf['text'].map(lambda s: len(s.split()))\n", - "edf = edf[['idx', 'num_tokens']]\n", - "fdf = mdf.merge(edf, left_on='ex_idx', right_on=\"idx\")\n", - "\n", - "mask = (fdf['num_tokens'] < 15) & (fdf['tp_count_expt'] >= 3)\n", - "fdf[mask].sort_values(by=\"f1_delta\", ascending=False).head(30)" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": { - "scrolled": true - }, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/usr/share/anaconda3/lib/python3.6/site-packages/ipykernel_launcher.py:5: FutureWarning: 'idx' is both an index level and a column label.\n", - "Defaulting to column, but this will raise an ambiguity error in a future version\n", - " \"\"\"\n" - ] - }, - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
ex_idxfn_count_basefp_count_basetn_count_basetp_count_baseprecision_baserecall_basef1_basefn_count_exptfp_count_expttn_count_expttp_count_exptprecision_exptrecall_exptf1_exptf1_deltaabs_f1_deltaidxnum_tokens
242411000.0000000.0000000.00000011000.0000000.0000000.0000000.0000000.000000249
3476347611000.0000000.0000000.00000011000.0000000.0000000.0000000.0000000.000000347619
3207320711000.0000000.0000000.00000011000.0000000.0000000.0000000.0000000.000000320714
2881288111000.0000000.0000000.00000011000.0000000.0000000.0000000.0000000.00000028814
2730273011000.0000000.0000000.00000011000.0000000.0000000.0000000.0000000.000000273013
2692269211000.0000000.0000000.00000011000.0000000.0000000.0000000.0000000.000000269211
2113211311000.0000000.0000000.00000011000.0000000.0000000.0000000.0000000.000000211314
1870187022110.3333330.3333330.33333322110.3333330.3333330.3333330.0000000.000000187018
2536253611000.0000000.0000000.00000011000.0000000.0000000.0000000.0000000.000000253612
1734173411000.0000000.0000000.00000011000.0000000.0000000.0000000.0000000.000000173412
42342311000.0000000.0000000.00000011000.0000000.0000000.0000000.0000000.00000042314
1807180722110.3333330.3333330.33333322110.3333330.3333330.3333330.0000000.000000180718
4491449111000.0000000.0000000.00000011000.0000000.0000000.0000000.0000000.000000449119
3096309611220.6666670.6666670.66666722110.3333330.3333330.333333-0.3333330.333333309611
797911220.6666670.6666670.66666722110.3333330.3333330.333333-0.3333330.333333797
13013000331.0000001.0000001.00000022110.3333330.3333330.333333-0.6666670.66666713017
3066306600331.0000001.0000001.00000022110.3333330.3333330.333333-0.6666670.666667306619
3866386600111.0000001.0000001.00000011000.0000000.0000000.000000-1.0000001.000000386616
1512151200111.0000001.0000001.00000011000.0000000.0000000.000000-1.0000001.000000151215
10910900111.0000001.0000001.00000011000.0000000.0000000.000000-1.0000001.00000010912
3247324700111.0000001.0000001.00000011000.0000000.0000000.000000-1.0000001.00000032479
3651365100111.0000001.0000001.00000011000.0000000.0000000.000000-1.0000001.000000365115
\n", - "
" - ], - "text/plain": [ - " ex_idx fn_count_base fp_count_base tn_count_base tp_count_base \\\n", - "24 24 1 1 0 0 \n", - "3476 3476 1 1 0 0 \n", - "3207 3207 1 1 0 0 \n", - "2881 2881 1 1 0 0 \n", - "2730 2730 1 1 0 0 \n", - "2692 2692 1 1 0 0 \n", - "2113 2113 1 1 0 0 \n", - "1870 1870 2 2 1 1 \n", - "2536 2536 1 1 0 0 \n", - "1734 1734 1 1 0 0 \n", - "423 423 1 1 0 0 \n", - "1807 1807 2 2 1 1 \n", - "4491 4491 1 1 0 0 \n", - "3096 3096 1 1 2 2 \n", - "79 79 1 1 2 2 \n", - "130 130 0 0 3 3 \n", - "3066 3066 0 0 3 3 \n", - "3866 3866 0 0 1 1 \n", - "1512 1512 0 0 1 1 \n", - "109 109 0 0 1 1 \n", - "3247 3247 0 0 1 1 \n", - "3651 3651 0 0 1 1 \n", - "\n", - " precision_base recall_base f1_base fn_count_expt fp_count_expt \\\n", - "24 0.000000 0.000000 0.000000 1 1 \n", - "3476 0.000000 0.000000 0.000000 1 1 \n", - "3207 0.000000 0.000000 0.000000 1 1 \n", - "2881 0.000000 0.000000 0.000000 1 1 \n", - "2730 0.000000 0.000000 0.000000 1 1 \n", - "2692 0.000000 0.000000 0.000000 1 1 \n", - "2113 0.000000 0.000000 0.000000 1 1 \n", - "1870 0.333333 0.333333 0.333333 2 2 \n", - "2536 0.000000 0.000000 0.000000 1 1 \n", - "1734 0.000000 0.000000 0.000000 1 1 \n", - "423 0.000000 0.000000 0.000000 1 1 \n", - "1807 0.333333 0.333333 0.333333 2 2 \n", - "4491 0.000000 0.000000 0.000000 1 1 \n", - "3096 0.666667 0.666667 0.666667 2 2 \n", - "79 0.666667 0.666667 0.666667 2 2 \n", - "130 1.000000 1.000000 1.000000 2 2 \n", - "3066 1.000000 1.000000 1.000000 2 2 \n", - "3866 1.000000 1.000000 1.000000 1 1 \n", - "1512 1.000000 1.000000 1.000000 1 1 \n", - "109 1.000000 1.000000 1.000000 1 1 \n", - "3247 1.000000 1.000000 1.000000 1 1 \n", - "3651 1.000000 1.000000 1.000000 1 1 \n", - "\n", - " tn_count_expt tp_count_expt precision_expt recall_expt f1_expt \\\n", - "24 0 0 0.000000 0.000000 0.000000 \n", - "3476 0 0 0.000000 0.000000 0.000000 \n", - "3207 0 0 0.000000 0.000000 0.000000 \n", - "2881 0 0 0.000000 0.000000 0.000000 \n", - "2730 0 0 0.000000 0.000000 0.000000 \n", - "2692 0 0 0.000000 0.000000 0.000000 \n", - "2113 0 0 0.000000 0.000000 0.000000 \n", - "1870 1 1 0.333333 0.333333 0.333333 \n", - "2536 0 0 0.000000 0.000000 0.000000 \n", - "1734 0 0 0.000000 0.000000 0.000000 \n", - "423 0 0 0.000000 0.000000 0.000000 \n", - "1807 1 1 0.333333 0.333333 0.333333 \n", - "4491 0 0 0.000000 0.000000 0.000000 \n", - "3096 1 1 0.333333 0.333333 0.333333 \n", - "79 1 1 0.333333 0.333333 0.333333 \n", - "130 1 1 0.333333 0.333333 0.333333 \n", - "3066 1 1 0.333333 0.333333 0.333333 \n", - "3866 0 0 0.000000 0.000000 0.000000 \n", - "1512 0 0 0.000000 0.000000 0.000000 \n", - "109 0 0 0.000000 0.000000 0.000000 \n", - "3247 0 0 0.000000 0.000000 0.000000 \n", - "3651 0 0 0.000000 0.000000 0.000000 \n", - "\n", - " f1_delta abs_f1_delta idx num_tokens \n", - "24 0.000000 0.000000 24 9 \n", - "3476 0.000000 0.000000 3476 19 \n", - "3207 0.000000 0.000000 3207 14 \n", - "2881 0.000000 0.000000 2881 4 \n", - "2730 0.000000 0.000000 2730 13 \n", - "2692 0.000000 0.000000 2692 11 \n", - "2113 0.000000 0.000000 2113 14 \n", - "1870 0.000000 0.000000 1870 18 \n", - "2536 0.000000 0.000000 2536 12 \n", - "1734 0.000000 0.000000 1734 12 \n", - "423 0.000000 0.000000 423 14 \n", - "1807 0.000000 0.000000 1807 18 \n", - "4491 0.000000 0.000000 4491 19 \n", - "3096 -0.333333 0.333333 3096 11 \n", - "79 -0.333333 0.333333 79 7 \n", - "130 -0.666667 0.666667 130 17 \n", - "3066 -0.666667 0.666667 3066 19 \n", - "3866 -1.000000 1.000000 3866 16 \n", - "1512 -1.000000 1.000000 1512 15 \n", - "109 -1.000000 1.000000 109 12 \n", - "3247 -1.000000 1.000000 3247 9 \n", - "3651 -1.000000 1.000000 3651 15 " - ] - }, - "execution_count": 14, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Find examples with no change\n", - "edf = p0.example_df.copy()\n", - "edf['num_tokens'] = edf['text'].map(lambda s: len(s.split()))\n", - "edf = edf[['idx', 'num_tokens']]\n", - "fdf = mdf.merge(edf, left_on='ex_idx', right_on=\"idx\")\n", - "\n", - "mask = (fdf['num_tokens'] < 20) \n", - "mask &= (fdf['tp_count_expt'] <= 2)\n", - "# mask &= fdf[\"tp_count_base\"] <= 1\n", - "mask &= fdf['f1_expt'] <= 0.5\n", - "fdf[mask].sort_values(by=\"abs_f1_delta\", ascending=True).head(30)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Plot the diffs on these examples\n", - "\n", - "The `ex_idx` column printed in each of the above cells is the index of that example in the lists of raw predictions. Enter it in the cell below to show the predictions (and ground truth) on base and expt for that example.\n", - "\n", - "By default, it will print all predicted classes with `p(class) > 0.5`, and give their predicted probabilities in parentheses." - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Text (14): the soldier was a religious man , one of his close help ##ers .\n", - "\n", - " span1: [ 0, 2)\t\"the soldier\"\n", - " span2: [ 9,10)\t\"his\"\n", - " label: (1)\t\t 0\n", - " pred: \t\t 1 (0.92)\n", - "\n", - "Text (14): the soldier was a religious man , one of his close help ##ers .\n", - "\n", - " span1: [ 0, 2)\t\"the soldier\"\n", - " span2: [ 9,10)\t\"his\"\n", - " label: (1)\t\t 0\n", - " pred: \t\t 1 (0.88)\n", - "\n" - ] - } - ], - "source": [ - "# ex_idx = 1868 # \"And their important leaders ...\"\n", - "# ex_idx = 1767 # \"Jesus looked at the man ...\"\n", - "# ex_idx = 2305 # \"He would not stop to help him either .\"\n", - "# ex_idx = 3476 # \"It wasn't until Lee Teng - Hui ...\"\n", - "# ex_idx = 4031 # only one local ringer\n", - "# ex_idx = 1734 # book of life\n", - "# ex_idx = 3066 # martha stewart\n", - "# ex_idx = 3866 # among its new customers\n", - "# ex_idx = 3651 # Tien stressed that the president ...\n", - "ex_idx = 2113\n", - "print(analysis.EdgeProbingExample(r0[ex_idx], label_vocab=p0.all_labels))\n", - "print(analysis.EdgeProbingExample(r1[ex_idx], label_vocab=p1.all_labels))" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.6.8" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/probing/generate_elmo_hdf5_weights.py b/probing/generate_elmo_hdf5_weights.py deleted file mode 100644 index 0243150e1..000000000 --- a/probing/generate_elmo_hdf5_weights.py +++ /dev/null @@ -1,88 +0,0 @@ -#!/usr/bin/env python - -# Helper script to generate ELMo weights file, where RNN weights are either randomized or -# randomized+orthogonalized.. -# Uses h5py to read in default ELMo weights file, make copy of it, and modify and save the copy. -# -# Usage: -# python generate_elmo_hdf5_weights.py -m random -s 0 -o name_of_weights_file.hdf5 -# -# Speed: takes around 6 seconds to generate random ELMo weight file and 10 -# seconds to generate orthogonal ELMo weight file. - -import argparse -import sys - -import h5py -import numpy as np -import torch - -import h5py_utils - -ELMO_WEIGHTS_PATH = "/nfs/jsalt/share/elmo/elmo_2x4096_512_2048cnn_2xhighway_weights.hdf5" - - -def main(args): - parser = argparse.ArgumentParser() - parser.add_argument( - "-m", - dest="elmo_model", - type=str, - required=True, - help="Type of ELMo weights: random or ortho.", - ) - parser.add_argument( - "-s", - dest="seed", - type=int, - required=True, - default=0, - help="Random seed for modifying RNN weights.", - ) - parser.add_argument( - "-o", - dest="output_filename", - type=str, - required=True, - help="Name of the output (hdf5 file containing modified ELMo weights).", - ) - args = parser.parse_args(args) - - elmo_model = args.elmo_model # Type of ELMo RNN weights: 'random' or 'ortho'. - np.random.seed(args.seed) - ELMo_weight_filename = args.output_filename # ELMo weights file to be written. - - assert elmo_model in ["random", "ortho"], "Failed to recognize flag elmo_model = " + elmo_model - - # ELMo_weight_filename = 'elmo_2x4096_512_2048cnn_2xhighway_weights_' + - # elmo_model + '_seed_' + str(args.seed) + '.hdf5' #Name of ELMo-weights - # file to be written. - - ELMo_weight_file = h5py_utils.copy_h5py_file(ELMO_WEIGHTS_PATH, ELMo_weight_filename) - - # Below is a list of h4py keys to all sets of weights in the LSTM. This - # list is found using the `.visit()` method. - list_of_paths_to_LSTM_weights = [ - "Cell0/LSTMCell/B", - "Cell0/LSTMCell/W_0", - "Cell0/LSTMCell/W_P_0", - "Cell1/LSTMCell/B", - "Cell1/LSTMCell/W_0", - "Cell1/LSTMCell/W_P_0", - ] - - for i in range(2): # BI-LSTM, so two RNNs - for path in list_of_paths_to_LSTM_weights: - weight_tensor = ELMo_weight_file["RNN_" + str(i) + "/RNN/MultiRNNCell/" + path] - shape = weight_tensor.shape - weight_tensor[...] = np.random.normal(0, 1, list(shape)) - # In case when we want to convert RNN weights to orthogonal matrices: - if elmo_model == "ortho" and (not path.endswith("/B")): - weight_torch_tensor = torch.tensor(np.array(weight_tensor[...])) - weight_tensor[...] = (torch.nn.init.orthogonal_(weight_torch_tensor)).numpy() - ELMo_weight_file.close() - - -if __name__ == "__main__": - main(sys.argv[1:]) - sys.exit(0) diff --git a/probing/get_and_process_all_data.sh b/probing/get_and_process_all_data.sh deleted file mode 100755 index 6b8eb4681..000000000 --- a/probing/get_and_process_all_data.sh +++ /dev/null @@ -1,108 +0,0 @@ -#!/bin/bash - -# Master script to re-generate all edge probing datasets. -# This script just follows the instructions in data/README.md; -# see that file and the individual dataset scripts for more details. -# -# Usage: -# # First, modify the paths below to point to OntoNotes and SPR1 on your system. -# ./get_and_process_all_data.sh /path/to/glue_data -# -# Note that OntoNotes is rather large and we need to process it several times, so -# this script can take a while to run. - -JIANT_DATA_DIR=${1:-"$HOME/glue_data"} # path to glue_data directory - -## Configure these for your environment ## -PATH_TO_ONTONOTES="/nfs/jsalt/home/iftenney/ontonotes/ontonotes/conll-formatted-ontonotes-5.0" -PATH_TO_SPR1_RUDINGER="/nfs/jsalt/home/iftenney/decomp.net/spr1" - -## Don't modify below this line. ## - -set -eux - -OUTPUT_DIR="${JIANT_DATA_DIR}/edges" -mkdir -p $OUTPUT_DIR -HERE=$(dirname $0) - -function preproc_task() { - TASK_DIR=$1 - # Extract data labels. - python $HERE/get_edge_data_labels.py -o $TASK_DIR/labels.txt \ - -i $TASK_DIR/*.json -s - # Retokenize for each tokenizer we need. - python $HERE/retokenize_edge_data.py -t "MosesTokenizer" $TASK_DIR/*.json - python $HERE/retokenize_edge_data.py -t "OpenAI.BPE" $TASK_DIR/*.json - python $HERE/retokenize_edge_data.py -t "bert-base-uncased" $TASK_DIR/*.json - python $HERE/retokenize_edge_data.py -t "bert-large-uncased" $TASK_DIR/*.json - - # Convert the original version to tfrecord. - python $HERE/convert_edge_data_to_tfrecord.py $TASK_DIR/*.json -} - -function get_ontonotes() { - ## OntoNotes (all tasks) - ## Gives ontonotes/{task}/{split}.json, - ## where task = {const, coref, ner, srl} - ## and split = {train, development, test, conll-2012-test} - # TODO: standardize filenames! - python $HERE/data/extract_ontonotes_all.py --ontonotes "${PATH_TO_ONTONOTES}" \ - --tasks const coref ner srl \ - --splits train development test conll-2012-test \ - -o $OUTPUT_DIR/ontonotes - - ## Gives ontonotes/const/{pos,nonterminal}/{split}.json - python $HERE/split_constituent_data.py $OUTPUT_DIR/ontonotes/const/*.json - - preproc_task $OUTPUT_DIR/ontonotes/const - preproc_task $OUTPUT_DIR/ontonotes/const/pos - preproc_task $OUTPUT_DIR/ontonotes/const/nonterminal - preproc_task $OUTPUT_DIR/ontonotes/coref - preproc_task $OUTPUT_DIR/ontonotes/ner - preproc_task $OUTPUT_DIR/ontonotes/srl -} - -function get_spr_dpr() { - ## SPR1 - ## Gives spr1/spr1.{split}.json, where split = {train, dev, test} - # TODO: standardize filenames! - python $HERE/data/convert-spr1-rudinger.py \ - -i ${PATH_TO_SPR1_RUDINGER}/*.json \ - -o $OUTPUT_DIR/spr1 - preproc_task $OUTPUT_DIR/spr1 - - ## SPR2 - ## Gives spr2/edges.{split}.json, where split = {train, dev, test} - # TODO: standardize filenames! - pip install conllu - bash $HERE/data/get_spr2_data.sh $OUTPUT_DIR/spr2 - preproc_task $OUTPUT_DIR/spr2 - - ## DPR - ## Gives dpr/{split}.json, where split = {train, dev, test} - bash $HERE/data/get_dpr_data.sh $OUTPUT_DIR/dpr - preproc_task $OUTPUT_DIR/dpr -} - -function get_ud() { - ## Universal Dependencies - ## Gives dep_ewt/en_ewt-ud-{split}.json, where split = {train, dev, test} - # TODO: standardize filenames! - bash $HERE/data/get_ud_data.sh $OUTPUT_DIR/dep_ewt - preproc_task $OUTPUT_DIR/dep_ewt -} - -function get_semeval() { - ## SemEval 2010 Task 8 relation classification - ## Gives semeval/{split}.json, where split = {train.0.85, dev, test} - mkdir $OUTPUT_DIR/semeval - bash $HERE/data/get_semeval_data.sh $OUTPUT_DIR/semeval - preproc_task $OUTPUT_DIR/semeval -} - -get_ontonotes -get_spr_dpr -get_ud - -get_semeval - diff --git a/probing/get_edge_data_labels.py b/probing/get_edge_data_labels.py deleted file mode 100755 index b88e1ae0d..000000000 --- a/probing/get_edge_data_labels.py +++ /dev/null @@ -1,70 +0,0 @@ -#!/usr/bin/env python - -# Helper script to extract set of labels from edge probing data. -# -# Usage: -# python get_edge_data_labels.py -o /path/to/edge/probing/data/labels.txt \ -# -i /path/to/edge/probing/data/*.json -# - -import argparse -import collections -import json -import logging as log -import os -import sys -from typing import Type - -from tqdm import tqdm - -from jiant.utils import utils - -log.basicConfig(format="%(asctime)s: %(message)s", datefmt="%m/%d %I:%M:%S %p", level=log.INFO) - - -def count_labels(fname: str) -> Type[collections.Counter]: - """Count labels across all targets in a file of edge probing examples.""" - label_ctr = collections.Counter() - record_iter = utils.load_json_data(fname) - for record in tqdm(record_iter): - for target in record["targets"]: - label = target["label"] - if isinstance(label, str): - label = [label] - label_ctr.update(label) - return label_ctr - - -def main(args): - parser = argparse.ArgumentParser() - parser.add_argument("-o", dest="output", type=str, required=True, help="Output file.") - parser.add_argument("-i", dest="inputs", type=str, nargs="+", help="Input files.") - parser.add_argument( - "-s", - dest="special_tokens", - type=str, - nargs="*", - default=["-"], - help="Additional special tokens to add at beginning " "of vocab list.", - ) - args = parser.parse_args(args) - - label_ctr = collections.Counter() - for fname in args.inputs: - log.info("Counting labels in %s", fname) - label_ctr.update(count_labels(fname)) - all_labels = args.special_tokens + sorted(label_ctr.keys()) - log.info( - "%d labels in total (%d special + %d found)", - len(all_labels), - len(args.special_tokens), - len(label_ctr), - ) - with open(args.output, "w") as fd: - for label in all_labels: - fd.write(label + "\n") - - -if __name__ == "__main__": - main(sys.argv[1:]) - sys.exit(0) diff --git a/probing/get_scalar_mix.py b/probing/get_scalar_mix.py deleted file mode 100755 index 837de1963..000000000 --- a/probing/get_scalar_mix.py +++ /dev/null @@ -1,95 +0,0 @@ -#!/usr/bin/env python - -# Script to extract final scalar mix weights from a model. -# Supports the weights as used by ELMo, and also those used by -# BertEmbedderModule when used in 'mix' mode. -# -# Usage: -# python get_scalar_mix.py -i /path/to/experiments/*/run \ -# -o /tmp/scalars.tsv -# -# Output will be a long-form TSV file containing aggregated and per-class -# predictions for each run. - -import sys -import os -import re -import json -import collections -import argparse -import glob -import copy -from tqdm import tqdm - -import logging as log - -import pandas as pd -import torch - -from typing import List, Tuple, Iterable, Dict - -log.basicConfig(format="%(asctime)s: %(message)s", datefmt="%m/%d %I:%M:%S %p", level=log.INFO) - - -def get_scalar(tensor): - assert tensor.size() == torch.Size([1]) - return tensor.numpy()[0] - - -def get_mix_scalars(checkpoint_path: str) -> Dict[str, Dict[str, float]]: - # Load and keep on CPU - data = torch.load(checkpoint_path, map_location=torch.device("cpu")) - # Find prefixes by matching names. - gamma_regex = r"^(.+\.scalar_mix(_\d+)?\.)gamma$" - prefixes = [m.group(1) for m in (re.match(gamma_regex, key) for key in data) if m] - # Extract scalar set for each prefix - ret = {} - for prefix in prefixes: - s = {} - for key in data: - if not key.startswith(prefix): - continue - s[key[len(prefix) :]] = get_scalar(data[key]) - ret[prefix] = s - return ret - - -def get_run_info(run_path: str, checkpoint_glob: str = "model_state_*.best.th") -> pd.DataFrame: - """Extract some run information from the log text.""" - checkpoint_paths = glob.glob(os.path.join(run_path, checkpoint_glob)) - checkpoint_paths += glob.glob(os.path.join(run_path, "*", checkpoint_glob)) - if not checkpoint_paths: - log.warning(f"Warning: no checkpoints found for run {run_path}") - - stats = [] - for checkpoint_path in checkpoint_paths: - scalars = get_mix_scalars(checkpoint_path) - for key in scalars: - r = copy.copy(scalars[key]) - r["run"] = run_path - r["checkpoint"] = checkpoint_path[len(run_path) :] - r["scalar_set"] = key - r["label"] = "__scalar_mix__" - stats.append(r) - return pd.DataFrame.from_records(stats) - - -def main(args): - parser = argparse.ArgumentParser() - parser.add_argument("-o", dest="output", type=str, default="", help="Output file (TSV).") - parser.add_argument("-i", dest="inputs", type=str, nargs="+", help="Input files.") - args = parser.parse_args(args) - - run_info = [get_run_info(path) for path in args.inputs] - run_info = pd.concat(run_info, axis=0, ignore_index=True, sort=False) - - if args.output: - log.info("Writing long-form stats table to %s", args.output) - run_info.to_csv(args.output, sep="\t") - else: - log.info("Stats:\n%s", str(run_info)) - - -if __name__ == "__main__": - main(sys.argv[1:]) - sys.exit(0) diff --git a/probing/h5py_utils.py b/probing/h5py_utils.py deleted file mode 100644 index d941b1f99..000000000 --- a/probing/h5py_utils.py +++ /dev/null @@ -1,23 +0,0 @@ -import h5py - - -def copy_h5py_file(src_filepath, dst_filename): - """Writes the content of a hdf5 file (specified by src_filepath) - to another hdf5 file (specified by dst_filename). - - Args: - src_filepath: a string specifying path of the source hdf5 file. - dst_filename: a string naming the dst_filename. If the file already exists, - then content in the original file will be written over. - - Returns: - A h5py File object which is a copy of the h5py File object corresponding - to src_filepath. - """ - src_file = h5py.File(src_filepath, "r") - dst_file = h5py.File(dst_filename, "w") - keys = list(src_file["/"].keys()) - for key in keys: - src_file["/"].copy(src_file["/" + key], dst_file["/"], name=key) - src_file.close() - return dst_file diff --git a/probing/install_extra_deps.sh b/probing/install_extra_deps.sh deleted file mode 100644 index eb49c80ce..000000000 --- a/probing/install_extra_deps.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash - -# Install extra dependencies for edge probing scripts (preprocessing). - -conda install ftfy=5.4.1 -conda install spacy=2.0.11 -python -m spacy download en diff --git a/probing/jiant b/probing/jiant deleted file mode 120000 index f4fbc77e9..000000000 --- a/probing/jiant +++ /dev/null @@ -1 +0,0 @@ -../jiant \ No newline at end of file diff --git a/probing/merge_predictions.py b/probing/merge_predictions.py deleted file mode 100755 index 04612fa54..000000000 --- a/probing/merge_predictions.py +++ /dev/null @@ -1,79 +0,0 @@ -#!/usr/bin/env python - -# Script to merge predictions from a series of runs on the same task. -# Use this to collapse the JSON prediction files into a single one, -# where targets.preds.proba will go from [num_labels] to [num_runs, num_labels] -# in the output, and all other fields are expected to be the same across runs. -# -# Usage: -# python merge_predictions.py \ -# -i /path/to/experiments/-*-/run/*_.json \ -# -o /path/to/experiments/-_.merged.json -# - -import sys -import os -import re -import json -import argparse -import glob -import copy -from tqdm import tqdm - -import logging as log - -log.basicConfig(format="%(asctime)s: %(message)s", datefmt="%m/%d %I:%M:%S %p", level=log.INFO) - -from data import utils -import pandas as pd - -from typing import List, Tuple, Iterable, Dict - - -def merge_records(records): - ret = copy.deepcopy(records[0]) - for target in ret["targets"]: - # Make a list we can extend - target["preds"]["proba"] = [] - - for r in records: - assert r["text"] == ret["text"] - assert len(r["targets"]) == len(ret["targets"]) - for i, target in enumerate(ret["targets"]): - assert r["targets"][i]["span1"] == target["span1"] - assert r["targets"][i].get("span2", None) == target.get("span2", None) - assert r["targets"][i]["label"] == target["label"] - target["preds"]["proba"].append(r["targets"][i]["preds"]["proba"]) - - return ret - - -def main(args): - parser = argparse.ArgumentParser() - parser.add_argument("-i", dest="inputs", type=str, nargs="+", help="Input files (json).") - parser.add_argument("-o", dest="output", type=str, required=True, help="Output file (json).") - args = parser.parse_args(args) - - # Sort inputs for stability. - preds_files = sorted(args.inputs) - log.info(f"Found {len(preds_files)} inputs:") - for fname in preds_files: - log.info(" " + fname) - - # Read the first file to count records. - num_records = sum(1 for line in open(preds_files[0])) - log.info(f"Found {num_records} lines in first file.") - - # Make parallel iterators for each file. - record_iters = [utils.load_json_data(fname) for fname in preds_files] - - # Merge records and write to file. - merge_iter = map(merge_records, zip(*record_iters)) - merge_iter = tqdm(merge_iter, total=num_records) - pd.options.display.float_format = "{:.2f}".format - utils.write_file_and_print_stats(merge_iter, args.output) - - -if __name__ == "__main__": - main(sys.argv[1:]) - sys.exit(0) diff --git a/probing/retokenize_bert.sh b/probing/retokenize_bert.sh deleted file mode 100755 index f8d63f874..000000000 --- a/probing/retokenize_bert.sh +++ /dev/null @@ -1,40 +0,0 @@ -#!/bin/bash - -set -eu - -EDGE_DATA_PATH="$JIANT_DATA_DIR/edges" -echo "Processing edge probing data in $EDGE_DATA_PATH" - -declare -a SUBPATHS -SUBPATHS+=( "spr1" ) -SUBPATHS+=( "spr2" ) -SUBPATHS+=( "dpr" ) -SUBPATHS+=( "dep_ewt" ) -SUBPATHS+=( "ontonotes/const/pos" ) -SUBPATHS+=( "ontonotes/const/nonterminal" ) -SUBPATHS+=( "ontonotes/srl" ) -SUBPATHS+=( "ontonotes/ner" ) -SUBPATHS+=( "ontonotes/coref" ) -SUBPATHS+=( "semeval" ) -SUBPATHS+=( "tacred/rel" ) -SUBPATHS+=( "noun_verb" ) - -for subpath in "${SUBPATHS[@]}"; do - python $(dirname $0)/retokenize_edge_data.py \ - -t bert-base-uncased $EDGE_DATA_PATH/$subpath/*.json & - python $(dirname $0)/retokenize_edge_data.py \ - -t bert-large-uncased $EDGE_DATA_PATH/$subpath/*.json & -done - -# exit 0 - -# Only use the cased model on NER, per https://arxiv.org/pdf/1810.04805.pdf -CASED_SUBPATHS=( "ontonotes/ner" ) - -for subpath in "${CASED_SUBPATHS[@]}"; do - python $(dirname $0)/retokenize_edge_data.py \ - -t bert-base-cased $EDGE_DATA_PATH/$subpath/*.json & - python $(dirname $0)/retokenize_edge_data.py \ - -t bert-large-cased $EDGE_DATA_PATH/$subpath/*.json & -done - diff --git a/probing/retokenize_edge_data.py b/probing/retokenize_edge_data.py deleted file mode 100755 index 6c45214fc..000000000 --- a/probing/retokenize_edge_data.py +++ /dev/null @@ -1,101 +0,0 @@ -#!/usr/bin/env python - -# Helper script to retokenize edge-probing data. -# Uses the given tokenizer, and saves results alongside the original files -# as .retokenized. -# -# Supported tokenizers: -# - MosesTokenizer -# - OpenAI.BPE: byte-pair-encoding model for OpenAI transformer LM; -# see https://github.com/openai/finetune-transformer-lm) -# - bert-*: wordpiece models for BERT; see https://arxiv.org/abs/1810.04805 -# and https://github.com/huggingface/pytorch-pretrained-BERT#usage -# -# Usage: -# python retokenize_edge_data.py /path/to/data/*.json -# -# Speed: takes around 2.5 minutes to process 90000 sentences on a single core. -# -# Note: for OpenAI.BPE, this requires the `spacy` and `ftfy` packages. -# These should only be needed for this script - main.py shouldn't need to do -# any further preprocessing. -# -# Note: for BERT tokenizers, this requires the 'pytorch_pretrained_bert' -# package. - -import argparse -import functools -import json -import logging as log -import multiprocessing -import os -import re -import sys -from typing import List, Text, Tuple - -from tqdm import tqdm - -from pytorch_pretrained_bert import BertTokenizer -from jiant.utils import retokenize, tokenizers, utils - -log.basicConfig(format="%(asctime)s: %(message)s", datefmt="%m/%d %I:%M:%S %p", level=log.INFO) - -PARSER = argparse.ArgumentParser() -PARSER.add_argument("-t", dest="tokenizer_name", type=str, required=True, help="Tokenizer name.") -PARSER.add_argument( - "--num_parallel", type=int, default=4, help="Number of parallel processes to use." -) -PARSER.add_argument("inputs", type=str, nargs="+", help="Input JSON files.") - -# For now, this module expects MosesTokenizer as the default. -# TODO: change this once we have better support in core utils. -MosesTokenizer = tokenizers.get_tokenizer("MosesTokenizer") -assert MosesTokenizer is not None - - -def retokenize_record(record, tokenizer_name): - """Retokenize an edge probing example. Modifies in-place.""" - text = record["text"] - aligner_fn = retokenize.get_aligner_fn(tokenizer_name) - ta, new_tokens = aligner_fn(text) - record["text"] = " ".join(new_tokens) - for target in record["targets"]: - if "span1" in target: - target["span1"] = list(map(int, ta.project_span(*target["span1"]))) - if "span2" in target: - target["span2"] = list(map(int, ta.project_span(*target["span2"]))) - return record - - -def _map_fn(line, tokenizer_name): - record = json.loads(line) - new_record = retokenize_record(record, tokenizer_name) - return json.dumps(new_record) - - -def retokenize_file(fname, tokenizer_name, worker_pool): - if tokenizer_name.startswith("nyu-mll/"): - new_name = fname + ".retokenized." + tokenizer_name.replace("/", ".") - else: - new_name = fname + ".retokenized." + tokenizer_name - log.info("Processing file: %s", fname) - inputs = list(utils.load_lines(fname)) - log.info(" saving to %s", new_name) - map_fn = functools.partial(_map_fn, tokenizer_name=tokenizer_name) - with open(new_name, "w") as fd: - for line in tqdm(worker_pool.imap(map_fn, inputs, chunksize=500), total=len(inputs)): - fd.write(line) - fd.write("\n") - - -def main(args): - args = PARSER.parse_args(args) - - worker_pool = multiprocessing.Pool(args.num_parallel) - for fname in args.inputs: - retokenize_file(fname, args.tokenizer_name, worker_pool=worker_pool) - - -if __name__ == "__main__": - main(sys.argv[1:]) - sys.exit(0) diff --git a/probing/split_constituent_data.py b/probing/split_constituent_data.py deleted file mode 100755 index 5fa035733..000000000 --- a/probing/split_constituent_data.py +++ /dev/null @@ -1,64 +0,0 @@ -#!/usr/bin/env python - -# Helper script to split constituent data into POS and nonterminal groups. -# -# TODO to integrate this into the OntoNotes processing script to generate in -# one shot. -# -# Usage: -# python split_constituent_data.py /path/to/edge/probing/data/*.json - -import copy -import json -import logging as log -import os -import sys - -from tqdm import tqdm - -from jiant.utils import utils - -log.basicConfig(format="%(asctime)s: %(message)s", datefmt="%m/%d %I:%M:%S %p", level=log.INFO) - - -def split_record(record): - pos_record = copy.deepcopy(record) - non_record = copy.deepcopy(record) - - pos_record["targets"] = [t for t in record["targets"] if t["info"]["height"] == 1] - non_record["targets"] = [t for t in record["targets"] if t["info"]["height"] > 1] - return (pos_record, non_record) - - -def split_file(fname): - dirname, base = os.path.split(fname) - - pos_dir = os.path.join(dirname, "pos") - os.makedirs(pos_dir, exist_ok=True) - new_pos_name = os.path.join(pos_dir, base) - - non_dir = os.path.join(dirname, "nonterminal") - os.makedirs(non_dir, exist_ok=True) - new_non_name = os.path.join(non_dir, base) - - log.info("Processing file: %s", fname) - record_iter = list(utils.load_json_data(fname)) - log.info(" saving to %s and %s", new_pos_name, new_non_name) - pos_fd = open(new_pos_name, "w") - non_fd = open(new_non_name, "w") - for record in tqdm(record_iter): - pos_record, non_record = split_record(record) - pos_fd.write(json.dumps(pos_record)) - pos_fd.write("\n") - non_fd.write(json.dumps(non_record)) - non_fd.write("\n") - - -def main(args): - for fname in args: - split_file(fname) - - -if __name__ == "__main__": - main(sys.argv[1:]) - sys.exit(0) diff --git a/pyproject.toml b/pyproject.toml index 013ed1297..79f3550b9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,16 +1,14 @@ [tool.black] line-length = 100 -target-version = ['py36', 'py37', 'py38'] include = '\.pyi?$' + exclude = ''' -/( - \.eggs - | \.git - | \.hg - | \.tox - | \.venv - | build - | dist -)/ +( + __pycache__ + | \.git + | \.mypy_cache + | \.pytest_cache + | \.venv +) ''' diff --git a/requirements-dev.txt b/requirements-dev.txt new file mode 100644 index 000000000..27bf52df3 --- /dev/null +++ b/requirements-dev.txt @@ -0,0 +1,9 @@ +-r requirements.txt +sphinx==1.8.1 +pytest==3.10.0 +pytest-cov==2.8.1 +pre-commit==2.3.0 +flake8==3.7.9 +flake8-docstrings==1.5.0 +black==19.10b0 +mypy==0.770 diff --git a/requirements-no-torch.txt b/requirements-no-torch.txt new file mode 100644 index 000000000..3ed44cb7a --- /dev/null +++ b/requirements-no-torch.txt @@ -0,0 +1,18 @@ +attrs==19.3.0 +bs4==0.0.1 +jsonnet==0.15.0 +lxml==4.5.1 +nlp==0.4.0 +nltk>=3.5 +numexpr==2.7.1 +numpy==1.18.4 +pandas==1.0.3 +python-Levenshtein==0.12.0 +sacremoses==0.0.43 +seqeval==0.0.12 +scikit-learn==0.22.2.post1 +scipy==1.4.1 +sentencepiece==0.1.86 +tokenizers==0.8.1.rc2 +tqdm==4.46.0 +transformers==3.0.2 diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 000000000..618044889 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +-r requirements-no-torch.txt +torch==1.5.0 +torchvision==0.6.0 diff --git a/scripts/ccg/README b/scripts/ccg/README deleted file mode 100644 index 8907c8fb3..000000000 --- a/scripts/ccg/README +++ /dev/null @@ -1,7 +0,0 @@ -To prepare the CCG data: -- Download CCGbank, available at: - https://catalog.ldc.upenn.edu/LDC2005T13 -- Place all scripts in this folder (ccg_processing_scripts) into the folder - ccgbank_1_1/data/AUTO within CCGbank -- Run the following line within this directory: ./ccg_prepare.sh - diff --git a/scripts/ccg/align_tags_to_bert.py b/scripts/ccg/align_tags_to_bert.py deleted file mode 100644 index a28805005..000000000 --- a/scripts/ccg/align_tags_to_bert.py +++ /dev/null @@ -1,97 +0,0 @@ -import argparse -import json -import os -import sys - -import pandas as pd - -from jiant.utils.retokenize import get_aligner_fn - - -""" -Usage: - Run the below command from the root directory - python -m scripts.ccg.align_tags_to_bert --data_dir {path/to/ccg/files} -t {tokenizer_name} - -The input file should be in csv form, with text and tags columns. - -The output format has columns text and tag, which is a string of space delimited numbers. -This preprocessing file will preprocess the CCG data using the tokenizer, -saving it alongside the original files. - -This file introduces a new tag to sub-words (if the tokenizer splits a word. -Currently, this supports BERT tokenization.) -For example, -[Mr., Porter] -> [Mr, ., Por, ter]. Thus, if Mr. was given a tag of 5 and Porter 6 -in the original CCG, then the alligned tags will be [5, 1363, 6, 1363], where 1363 indicates -a subpiece of a word that has been split due to tokenization. -""" - - -def get_tags(text, current_tags, tokenizer_name, tag_dict): - aligner_fn = get_aligner_fn(tokenizer_name) - assert len(text) == len(current_tags) - introduced_tokenizer_tag = len(tag_dict) - token_aligner, aligned_text = aligner_fn(" ".join(text)) - aligned_tags = [introduced_tokenizer_tag for token in aligned_text] - for text_idx, text_tag in enumerate(current_tags): - aligned_idx = token_aligner.project_tokens(text_idx)[0] - aligned_tags[aligned_idx] = tag_dict[text_tag] - str_tags = [str(s) for s in aligned_tags] - return " ".join(str_tags) - - -def align_tags_BERT(dataset, tokenizer_name, tags_to_id): - new_pandas = [] - for i in range(len(dataset)): - row = dataset.iloc[i] - text = row["text"].split() - current_tags = row["tags"].split() - tags = get_tags(text, current_tags, tokenizer_name, tags_to_id) - new_pandas.append([row["text"], tags]) - result = pd.DataFrame(new_pandas, columns=["text", "tags"]) - return result - - -def align_ccg(split, tokenizer_name, data_dir): - """ - We align BERT tags such that any introduced tokens introudced - by BERT will be assigned a special tag, which later on in - preprocessing/task building will be converted into a tag mask (so that - we do not take into account the model prediction for tokens introduced by - the tokenizer). - - Args - -------------- - split: str, - tokenizer_name: str, - data_dir: str, - - Returns - -------------- - None, saves tag alligned files to same directory as the original file. - """ - tags_to_id = json.load(open(data_dir + "tags_to_id.json", "r")) - ccg_text = pd.read_csv( - os.path.join(data_dir, "ccg." + split), names=["text", "tags"], delimiter="\t" - ) - result = align_tags_BERT(ccg_text, tokenizer_name, tags_to_id) - result.to_csv(os.path.join(data_dir, "ccg." + split + "." + tokenizer_name), sep="\t") - - -def main(arguments): - parser = argparse.ArgumentParser() - parser.add_argument( - "-d", "--data_dir", help="directory to save data to", type=str, default="../data" - ) - parser.add_argument( - "-t", "--tokenizer", help="intended tokenization", type=str, default="MosesTokenizer" - ) - args = parser.parse_args(arguments) - align_ccg("train", args.tokenizer, args.data_dir) - align_ccg("dev", args.tokenizer, args.data_dir) - align_ccg("test", args.tokenizer, args.data_dir) - - -if __name__ == "__main__": - sys.exit(main(sys.argv[1:])) diff --git a/scripts/ccg/ccg_prepare.sh b/scripts/ccg/ccg_prepare.sh deleted file mode 100755 index 42ec75d23..000000000 --- a/scripts/ccg/ccg_prepare.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash - -pushd $(dirname $0) -python ccg_proc.py -python ccg_to_num.py -python moses_aligner.py ccg_num.train -python moses_aligner.py ccg_num.dev -python moses_aligner.py ccg_num.test -python zipper.py ccg_num.train ccg_num.train.moses -python zipper.py ccg_num.dev ccg_num.dev.moses -python zipper.py ccg_num.test ccg_num.test.moses -mv ccg_num.train.zipped ccg_1363.train -mv ccg_num.dev.zipped ccg_1363.dev -mv ccg_num.test.zipped ccg_1363.test - - diff --git a/scripts/ccg/ccg_proc.py b/scripts/ccg/ccg_proc.py deleted file mode 100644 index 3f45e403c..000000000 --- a/scripts/ccg/ccg_proc.py +++ /dev/null @@ -1,107 +0,0 @@ -import os -import sys - -# First create the training set -fo = open("ccg.train", "w") - -# Standard training split -directories = [ - "00", - "01", - "02", - "03", - "04", - "05", - "06", - "07", - "08", - "09", - "10", - "11", - "12", - "13", - "14", - "15", - "16", - "17", - "18", -] - -for directory in directories: - for filename in os.listdir(directory): - fi = open(directory + "/" + filename) - - # Extract sentences and just their tags - for line in fi: - if "<" in line: - sentence = [] - tags = [] - - items = line.strip().split("<") - for item in items: - parts = item.split() - - if parts[0] == "L": - sentence.append(parts[4]) - tags.append(parts[1]) - - # Write to file - if len(sentence) == len(tags): - fo.write(" ".join(sentence) + "\t" + " ".join(tags) + "\n") - -# Then the dev set -fo = open("ccg.dev", "w") - -# Standard dev split -directories = ["19", "20", "21"] - -for directory in directories: - for filename in os.listdir(directory): - fi = open(directory + "/" + filename) - - # Extract sentences and just their tags - for line in fi: - if "<" in line: - sentence = [] - tags = [] - - items = line.strip().split("<") - for item in items: - parts = item.split() - - if parts[0] == "L": - sentence.append(parts[4]) - tags.append(parts[1]) - - # Write to file - if len(sentence) == len(tags): - fo.write(" ".join(sentence) + "\t" + " ".join(tags) + "\n") - - -# And finally the test set -fo = open("ccg.test", "w") - -# Standard test split -directories = ["22", "23", "24"] - -for directory in directories: - for filename in os.listdir(directory): - fi = open(directory + "/" + filename) - - # Extract sentences and just their tags - for line in fi: - if "<" in line: - sentence = [] - tags = [] - - items = line.strip().split("<") - for item in items: - parts = item.split() - - if parts[0] == "L": - sentence.append(parts[4]) - tags.append(parts[1]) - - # Write to file - if len(sentence) == len(tags): - fo.write(" ".join(sentence) + "\t" + " ".join(tags) + "\n") diff --git a/scripts/ccg/ccg_to_num.py b/scripts/ccg/ccg_to_num.py deleted file mode 100644 index 1b57fec58..000000000 --- a/scripts/ccg/ccg_to_num.py +++ /dev/null @@ -1,84 +0,0 @@ -fi1 = open("ccg.train", "r") -fi2 = open("ccg.test", "r") -fi3 = open("ccg.dev", "r") - -fo1 = open("ccg_num.train", "w") -fo2 = open("ccg_num.test", "w") -fo3 = open("ccg_num.dev", "w") - - -tag2num = {} - -counter = 0 - -for line in fi1: - parts = line.strip().split("\t") - tags = parts[1].split() - - for tag in tags: - if tag not in tag2num: - tag2num[tag] = str(counter) - counter += 1 - -for line in fi2: - parts = line.strip().split("\t") - tags = parts[1].split() - - for tag in tags: - if tag not in tag2num: - tag2num[tag] = str(counter) - counter += 1 - - -for line in fi3: - parts = line.strip().split("\t") - tags = parts[1].split() - - for tag in tags: - if tag not in tag2num: - tag2num[tag] = str(counter) - counter += 1 - -fi1.close() -fi2.close() -fi3.close() - -print(counter) - - -fi1 = open("ccg.train", "r") -fi2 = open("ccg.test", "r") -fi3 = open("ccg.dev", "r") - -for line in fi1: - parts = line.strip().split("\t") - sent = parts[0] - tags = parts[1].split() - - nums = [] - for tag in tags: - nums.append(tag2num[tag]) - - fo1.write(sent + "\t" + " ".join(nums) + "\n") - -for line in fi2: - parts = line.strip().split("\t") - sent = parts[0] - tags = parts[1].split() - - nums = [] - for tag in tags: - nums.append(tag2num[tag]) - - fo2.write(sent + "\t" + " ".join(nums) + "\n") - -for line in fi3: - parts = line.strip().split("\t") - sent = parts[0] - tags = parts[1].split() - - nums = [] - for tag in tags: - nums.append(tag2num[tag]) - - fo3.write(sent + "\t" + " ".join(nums) + "\n") diff --git a/scripts/ccg/moses_aligner.py b/scripts/ccg/moses_aligner.py deleted file mode 100644 index f1a6af92d..000000000 --- a/scripts/ccg/moses_aligner.py +++ /dev/null @@ -1,50 +0,0 @@ -import sys - -from nltk.tokenize.moses import MosesTokenizer - -TOK = MosesTokenizer() - -fi = open(sys.argv[1], "r") -fo = open(sys.argv[1] + ".moses", "w") - -for line in fi: - parts = line.strip().split("\t") - old_toks = parts[0].split() - new_toks = TOK.tokenize(parts[0]) - tags = parts[1].split() - - new_tags = [] - tag_counter = 0 - next_covered = 0 - for index, word in enumerate(new_toks): - if next_covered > 0: - next_covered -= 1 - continue - - if word == old_toks[tag_counter].replace("&", "&").replace("'", "'"): - new_tags.append(tags[tag_counter]) - tag_counter += 1 - else: - for i in range(7): - if word + "".join(new_toks[index + 1 : index + 1 + i + 1]) == old_toks[ - tag_counter - ].replace("&", "&").replace("'", "'"): - for k in range(i + 2): - new_tags.append(tags[tag_counter]) - tag_counter += 1 - next_covered = i + 1 - break - - if next_covered == 0: - print("ERROR!", word, word + new_toks[index + 1], old_toks[tag_counter]) - print(" ".join(old_toks)) - print(" ".join(new_toks)) - print(" ") - if len(new_tags) != len(new_toks): - print("MISMATCH!!!") - - fo.write( - (" ".join(new_toks) + "\t" + " ".join(new_tags) + "\n") - .replace("&", "&") - .replace("'", "'") - ) diff --git a/scripts/ccg/zipper.py b/scripts/ccg/zipper.py deleted file mode 100644 index 5a840c5d4..000000000 --- a/scripts/ccg/zipper.py +++ /dev/null @@ -1,13 +0,0 @@ -import sys - -fi1 = open(sys.argv[1], "r") -fi2 = open(sys.argv[2], "r") - -fo1 = open(sys.argv[1] + ".zipped", "w") - - -lines1 = fi1.readlines() -lines2 = fi2.readlines() - -for index, line in enumerate(lines1): - fo1.write(line.strip().split("\t")[0] + "\t" + lines2[index].strip().split("\t")[1] + "\n") diff --git a/scripts/demo.sh b/scripts/demo.sh deleted file mode 100755 index 4091f977d..000000000 --- a/scripts/demo.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash - -# Quick-start: use path_config.sh to set up your environment variables, then run this -pushd "${PWD%jiant*}jiant" # Make sure we're in the base jiant directory -python main.py --config_file jiant/config/demo.conf diff --git a/scripts/demo.with_docker.sh b/scripts/demo.with_docker.sh deleted file mode 100755 index cc4bbe3e4..000000000 --- a/scripts/demo.with_docker.sh +++ /dev/null @@ -1,47 +0,0 @@ -#!/bin/bash - -# Run jiant with demo.conf in a docker container. -# -# The container expects a number of paths relative to /nfs/jsalt; -# for now, we'll fake these by setting up a temp directory. -# -# TODO to replace this with a properly-agnostic mount point inside the -# container. -# -# TODO: turn this into a real integration test... - -# temporarily cd to jiant/ -pushd $(dirname $0) -pushd $(git rev-parse --show-toplevel) - -set -eux - -# Get the path to this repo; we'll mount it from the container later. -JIANT_PATH=$(readlink -f .) - -NFS_PATH="/nfs/jiant" # absolute path to NFS volume -mkdir -p $NFS_PATH/exp/$USER # project directory - -# Build the docker image. This will be slow the first time you run it, -# but will cache steps for subsequent runs. -IMAGE_NAME="jiant-sandbox:demo" -sudo docker build --build-arg "NFS_MOUNT=$NFS_PATH" -t $IMAGE_NAME . - -# This is the python command we'll actually run, with paths relative to the -# container root. See the -v "src:dst" flags below for the mapping. -declare -a COMMAND -COMMAND+=( python $NFS_PATH/jiant/main.py ) -COMMAND+=( --config_file $NFS_PATH/jiant/jiant/config/demo.conf ) -COMMAND+=( -o "exp_name=jiant-demo" ) - -# Run demo.conf in the docker container. -sudo docker run --runtime=nvidia --rm \ - -v "$NFS_PATH:$NFS_PATH" \ - -v "$JIANT_PATH:$NFS_PATH/jiant" \ - -e "JIANT_DATA_DIR=$JIANT_DATA_DIR" \ - -e "ELMO_SRC_DIR=$ELMO_SRC_DIR" \ - -e "WORD_EMBS_FILE=$WORD_EMBS_FILE" \ - -e "JIANT_PROJECT_PREFIX=$NFS_PATH/exp/$USER" \ - -e "HUGGINGFACE_TRANSFORMERS_CACHE=$HUGGINGFACE_TRANSFORMERS_CACHE" \ - --user $(id -u):$(id -g) \ - -i ${IMAGE_NAME} "${COMMAND[@]}" diff --git a/scripts/dissent/README b/scripts/dissent/README deleted file mode 100644 index d866136a1..000000000 --- a/scripts/dissent/README +++ /dev/null @@ -1,14 +0,0 @@ -To create the DisSent data: -- Download the corpus or corpora of your choice; we use the following 2: - - WikiText-103: https://einstein.ai/research/the-wikitext-long-term-dependency-language-modeling-dataset - - Billion Word Benchmark: http://www.statmt.org/lm-benchmark/ -- Dependency parse your corpus using the Stanford CoreNLP dependency parser. Create separate files for training, dev, and test sets (but, for each set, there should be just a single file containing all dependency parses). Your command will probably follow this format: - java -Xmx2g -cp "*" edu.stanford.nlp.parser.nndep.DependencyParser -model edu/stanford/nlp/models/parser/nndep/english_UD.gz -textFile wikitext103.train wikitext103.train.parsed -- For each of these parse files, run the following command: - python dissent_corpus_maker.py FILENAME.parsed FILENAME.dissent_prelim -- For each of these output files, run the following command: - python dissent_postproc.py FILENAME.dissent_prelim FILENAME.dissent - -These final .dissent files will be the files you can use to train the system. - - diff --git a/scripts/dissent/dissent_corpus_maker.py b/scripts/dissent/dissent_corpus_maker.py deleted file mode 100644 index 7c7177784..000000000 --- a/scripts/dissent/dissent_corpus_maker.py +++ /dev/null @@ -1,358 +0,0 @@ -import re -import sys - -wiki = open(sys.argv[1], "r") -fo = open(sys.argv[2], "w") - - -word_list = [] -parent_list = [] -rel_list = [] - -marked = 0 -root_index = -1 - -sent_counter = 0 - - -def alphanum_core(string): - words = string.split() - - seen_letters = 0 - sentence_new = [] - for word in words: - if any(c.isalpha() for c in word): # re.search('[a-zA-Z0-9]', word) == 1: - seen_letters = 1 - if seen_letters: - sentence_new.append(word) - - final_has_letters = 0 - for word_ind, word in enumerate(sentence_new): - if any(c.isalpha() for c in word): # re.search('[a-zA-Z0-9]', word) == 1: - final_has_letters = word_ind - - return " ".join(sentence_new[: final_has_letters + 1]) - - -def external_punc_remover(string): - words = string.split() - if len(words) == 0: - return string - - if words[0] in [".", ",", "/", ":", ";", "?", "!"]: - return external_punc_remover(" ".join(words[1:])) - if words[-1] in [".", ",", "/", ":", ";", "?", "!"]: - return external_punc_remover(" ".join(words[:-1])) - - if words[0] == "'" and "'" not in alphanum_core(string): - return external_punc_remover(" ".join(words[1:])) - if words[-1] == "'" and "'" not in alphanum_core(string): - return external_punc_remover(" ".join(words[:-1])) - if words[0] == '"' and '"' not in alphanum_core(string): - return external_punc_remover(" ".join(words[1:])) - if words[-1] == '"' and '"' not in alphanum_core(string): - return external_punc_remover(" ".join(words[:-1])) - - if words[0] == "''" and "''" not in alphanum_core(string): - return external_punc_remover(" ".join(words[1:])) - if words[-1] == "''" and "''" not in alphanum_core(string): - return external_punc_remover(" ".join(words[:-1])) - - return string - - -def parent_function( - parent_list, this_index, desired_parent, rel_list, opaque_index_1, opaque_index_2 -): - if this_index == desired_parent: - return -1 - # or rel_list[this_index] == "conj" or rel_list[this_index] == "advcl" or - # rel_list[this_index] == "punct" or rel_list[this_index] == "cc": - if parent_list[this_index] == 0 or this_index == opaque_index_1 or this_index == opaque_index_2: - return 0 - elif parent_list[this_index] == desired_parent + 1: - return -1 - else: - return parent_list[this_index] - - -def get_all_descendants(word_list, parent_list, index, rel_list, opaque_index_1, opaque_index_2): - binary = [] - for this_index, parent in enumerate(parent_list): - done = 0 - while not done: - this_par = parent_function( - parent_list, this_index, index, rel_list, opaque_index_1, opaque_index_2 - ) - if this_par == 0 or this_par == -1: - in_out = this_par * -1 - binary.append(in_out) - done = 1 - else: - this_index = this_par - 1 - - connected = 0 - ended = 0 - - checked_r = 0 - to_add = 0 - seen_zero = 0 - while not checked_r: - this_digit = binary[index + to_add] - if this_digit == 0: - seen_zero = 1 - if seen_zero: - binary[index + to_add] = 0 - if index + to_add == len(binary) - 1: - checked_r = 1 - to_add += 1 - checked_l = 0 - to_add = 0 - seen_zero = 0 - while not checked_l: - this_digit = binary[index - to_add] - if this_digit == 0: - seen_zero = 1 - if seen_zero: - binary[index - to_add] = 0 - if index - to_add == 0: - checked_l = 1 - to_add += 1 - - for bin_index, digit in enumerate(binary): - if digit == 1: - connected = 1 - if connected and digit == 0 and rel_list[bin_index] == "punct": - binary[bin_index] = 1 - elif connected and digit == 0: - ended = 1 - if ended and digit == 1: - connected = 0 - - if not connected: - return -1 - - sentence = [] - started = 0 - for index, value in enumerate(binary): - if value == 1: - if started == 0: - started = 1 - if rel_list[index] != "mark": - sentence.append(word_list[index]) - else: - sentence.append(word_list[index]) - - return " ".join(sentence) - - seen_letters = 0 - sentence_new = [] - for word in sentence: - if any(c.isalpha() for c in word): # re.search('[a-zA-Z0-9]', word) == 1: - seen_letters = 1 - if seen_letters: - sentence_new.append(word) - - final_has_letters = 0 - for word_ind, word in enumerate(sentence_new): - if any(c.isalpha() for c in word): # re.search('[a-zA-Z0-9]', word) == 1: - final_has_letters = word_ind - - return " ".join(sentence_new[: final_has_letters + 1]) - - -def has_subj(rel_list, parent_list, index): - - for rel_index, rel in enumerate(rel_list): - if rel == "nsubj" and parent_list[rel_index] == index + 1: - return 1 - - return 0 - - -prev_sent = "" -for line in wiki: - sent_counter += 1 - if sent_counter % 100000 == 0: - print(sent_counter) - if sent_counter == 0: - print(sys.argv[1]) - - if len(line) <= 2: - - if marked == 1: - for index, word in enumerate(word_list): - if rel_list[index] == "root": - root_index = index - - for index, word in enumerate(word_list): - - if ( - word.lower() == "because" - or word.lower() == "if" - or word.lower() == "before" - or word.lower() == "so" - or word.lower() == "though" - ): - if rel_list[index] == "mark" or rel_list[index] == "advmod": - parent = parent_list[index] - 1 - grandparent = parent_list[parent] - 1 - if ( - rel_list[parent] == "advcl" - and has_subj(rel_list, parent_list, grandparent) - and has_subj(rel_list, parent_list, parent) - ): - sent1 = get_all_descendants( - word_list, parent_list, grandparent, rel_list, index, parent - ) - sent2 = get_all_descendants( - word_list, parent_list, parent, rel_list, index, index - ) - connector = word - fo.write( - external_punc_remover(sent1) - + "\t" - + external_punc_remover(sent2) - + "\t" - + connector - + "\n" - ) - elif grandparent == -1: - if index == 0: - sent1 = prev_sent - sent2 = " ".join(word_list[1:]) - connector = word - fo.write( - external_punc_remover(sent1) - + "\t" - + external_punc_remover(sent2) - + "\t" - + connector - + "\n" - ) - # pass # Here is where it would be previous sentence - else: - continue - if word.lower() == "when": - if rel_list[index] == "advmod": - parent = parent_list[index] - 1 - grandparent = parent_list[parent] - 1 - if ( - rel_list[parent] == "advcl" - and has_subj(rel_list, parent_list, grandparent) - and has_subj(rel_list, parent_list, parent) - ): - sent1 = get_all_descendants( - word_list, parent_list, grandparent, rel_list, index, parent - ) - sent2 = get_all_descendants( - word_list, parent_list, parent, rel_list, index, index - ) - connector = word - fo.write( - external_punc_remover(sent1) - + "\t" - + external_punc_remover(sent2) - + "\t" - + connector - + "\n" - ) - elif False: # grandparent == -1: - if index == 0: - sent1 = prev_sent - sent2 = " ".join(word_list[1:]) - connector = word - fo.write( - external_punc_remover(sent1) - + "\t" - + external_punc_remover(sent2) - + "\t" - + connector - + "\n" - ) - - # pass # Here is where it would be previous sentence - else: - continue - - if word.lower() == "and" or word.lower() == "but": - if rel_list[index] == "cc": - parent = parent_list[index] - 1 - if has_subj(rel_list, parent_list, parent): - has_conjunct = 0 - for rel_index, rel in enumerate(rel_list): - if ( - rel == "conj" - and parent_list[rel_index] - 1 == parent - and has_subj(rel_list, parent_list, rel_index) - and rel_index > index - ): - sent1 = get_all_descendants( - word_list, parent_list, parent, rel_list, index, index - ) - sent2 = get_all_descendants( - word_list, parent_list, rel_index, rel_list, index, index - ) - connector = word - fo.write( - external_punc_remover(sent1) - + "\t" - + external_punc_remover(sent2) - + "\t" - + connector - + "\n" - ) - has_conjunct = 1 - if not has_conjunct: - if index == 0: - sent1 = prev_sent - sent2 = " ".join(word_list[1:]) - connector = word - fo.write( - external_punc_remover(sent1) - + "\t" - + external_punc_remover(sent2) - + "\t" - + connector - + "\n" - ) - - # pass # Here is where it would be previous sentence - - prev_sent = " ".join(word_list) - word_list = [] - parent_list = [] - rel_list = [] - root_index = -1 - - marked = 0 - continue - - this_rel = line.split("(")[0] - end_parts = line[line.index("(") + 1 :].split() - this_word = end_parts[1].split("-")[0] - this_parent = int(end_parts[0].split("-")[-1][:-1]) - - word_list.append(this_word) - rel_list.append(this_rel) - parent_list.append(this_parent) - - if this_word.lower() == "and" or this_word.lower() == "but": - if this_rel == "cc": - - marked = 1 - - if ( - this_word.lower() == "because" - or this_word.lower() == "if" - or this_word.lower() == "before" - or this_word.lower() == "though" - or this_word.lower() == "so" - ): - - if this_rel == "mark" or this_rel == "advmod": - marked = 1 - - if this_word.lower() == "when": - if this_rel == "advmod": - marked = 1 diff --git a/scripts/dissent/dissent_postproc.py b/scripts/dissent/dissent_postproc.py deleted file mode 100644 index cbaafca5e..000000000 --- a/scripts/dissent/dissent_postproc.py +++ /dev/null @@ -1,52 +0,0 @@ -import sys - -fi = open(sys.argv[1], "r") -fo = open(sys.argv[2], "w") - -label_dict = {} - - -def remove_punc(sent): - words = sent.split() - - new_words = [] - seen_word = 0 - for word in words: - if not seen_word and len(word) == 1 and not word.isalnum(): - pass - else: - seen_word = 1 - new_words.append(word) - - words = new_words[::-1] - new_new_words = [] - seen_word = 0 - for word in words: - if not seen_word and len(word) == 1 and not word.isalnum(): - pass - else: - seen_word = 1 - new_new_words.append(word) - return " ".join(new_new_words[::-1]) - - -label_count = 0 -for line in fi: - parts = line.strip().split("\t") - sent1 = parts[0] - sent2 = parts[1] - label = parts[2] - - sent1 = remove_punc(sent1) - sent2 = remove_punc(sent2) - - sent1 = sent1[0].upper() + sent1[1:] + " ." - sent2 = sent2[0].upper() + sent2[1:] + " ." - - if label.lower() not in label_dict: - label_dict[label] = label_count - label_count += 1 - - label = str(label_dict[label.lower()]) - - fo.write(sent1 + "\t" + sent2 + "\t" + label + "\n") diff --git a/scripts/download_glue_data.py b/scripts/download_glue_data.py deleted file mode 100755 index fe1bfc8be..000000000 --- a/scripts/download_glue_data.py +++ /dev/null @@ -1,174 +0,0 @@ -#!/usr/bin/env python3 - -""" Script for downloading all GLUE data. - -Example usage: - python download_glue_data.py --data_dir data --tasks all - -Note: for legal reasons, we are unable to host MRPC. -You can either use the version hosted by the SentEval team, which is already tokenized, -or you can download the original data from: -https://download.microsoft.com/download/D/4/6/D46FF87A-F6B9-4252-AA8B-3604ED519838/MSRParaphraseCorpus.msi # noqa -and extract the data from it manually. -For Windows users, you can run the .msi file. For Mac and Linux users, consider an external library -such as 'cabextract' (see below for an example). You should then rename and place specific files in -a folder (see below for an example). - -mkdir MRPC -cabextract MSRParaphraseCorpus.msi -d MRPC -cat MRPC/_2DEC3DBE877E4DB192D17C0256E90F1D | tr -d $'\r' > MRPC/msr_paraphrase_train.txt -cat MRPC/_D7B391F9EAFF4B1B8BCE8F21B20B1B61 | tr -d $'\r' > MRPC/msr_paraphrase_test.txt -rm MRPC/_* -rm MSRParaphraseCorpus.msi - -""" - -import os -import sys -import shutil -import argparse -import tempfile -import urllib.request -import zipfile - -TASKS = ["CoLA", "SST", "MRPC", "QQP", "STS", "MNLI", "SNLI", "QNLI", "RTE", "WNLI", "diagnostic"] -TASK2PATH = { - "CoLA": "https://dl.fbaipublicfiles.com/glue/data/CoLA.zip", - "SST": "https://dl.fbaipublicfiles.com/glue/data/SST-2.zip", - "MRPC": "https://dl.fbaipublicfiles.com/glue/data/mrpc_dev_ids.tsv", - "QQP": "https://dl.fbaipublicfiles.com/glue/data/QQP-clean.zip", - "STS": "https://dl.fbaipublicfiles.com/glue/data/STS-B.zip", - "MNLI": "https://dl.fbaipublicfiles.com/glue/data/MNLI.zip", - "SNLI": "https://dl.fbaipublicfiles.com/glue/data/SNLIv2.zip", - "QNLI": "https://dl.fbaipublicfiles.com/glue/data/QNLIv2.zip", - "RTE": "https://dl.fbaipublicfiles.com/glue/data/RTE.zip", - "WNLI": "https://dl.fbaipublicfiles.com/glue/data/WNLI.zip", - "diagnostic": [ - "https://dl.fbaipublicfiles.com/glue/data/AX.tsv", - "https://dl.fbaipublicfiles.com/glue/data/diagnostic-full.tsv", - ], -} - -MRPC_TRAIN = "https://dl.fbaipublicfiles.com/senteval/senteval_data/msr_paraphrase_train.txt" -MRPC_TEST = "https://dl.fbaipublicfiles.com/senteval/senteval_data/msr_paraphrase_test.txt" - - -def download_and_extract(task, data_dir): - print("Downloading and extracting %s..." % task) - data_file = "%s.zip" % task - urllib.request.urlretrieve(TASK2PATH[task], data_file) - with zipfile.ZipFile(data_file) as zip_ref: - zip_ref.extractall(data_dir) - os.remove(data_file) - print("\tCompleted!") - - -def format_mrpc(data_dir, path_to_data): - print("Processing MRPC...") - mrpc_dir = os.path.join(data_dir, "MRPC") - if not os.path.isdir(mrpc_dir): - os.mkdir(mrpc_dir) - if path_to_data: - mrpc_train_file = os.path.join(path_to_data, "msr_paraphrase_train.txt") - mrpc_test_file = os.path.join(path_to_data, "msr_paraphrase_test.txt") - else: - print("Local MRPC data not specified, downloading data from %s" % MRPC_TRAIN) - mrpc_train_file = os.path.join(mrpc_dir, "msr_paraphrase_train.txt") - mrpc_test_file = os.path.join(mrpc_dir, "msr_paraphrase_test.txt") - urllib.request.urlretrieve(MRPC_TRAIN, mrpc_train_file) - urllib.request.urlretrieve(MRPC_TEST, mrpc_test_file) - assert os.path.isfile(mrpc_train_file), "Train data not found at %s" % mrpc_train_file - assert os.path.isfile(mrpc_test_file), "Test data not found at %s" % mrpc_test_file - urllib.request.urlretrieve(TASK2PATH["MRPC"], os.path.join(mrpc_dir, "dev_ids.tsv")) - - dev_ids = [] - with open(os.path.join(mrpc_dir, "dev_ids.tsv"), encoding="utf8") as ids_fh: - for row in ids_fh: - dev_ids.append(row.strip().split("\t")) - - with open(mrpc_train_file, encoding="utf8") as data_fh, open( - os.path.join(mrpc_dir, "train.tsv"), "w", encoding="utf8" - ) as train_fh, open(os.path.join(mrpc_dir, "dev.tsv"), "w", encoding="utf8") as dev_fh: - header = data_fh.readline() - train_fh.write(header) - dev_fh.write(header) - for row in data_fh: - label, id1, id2, s1, s2 = row.strip().split("\t") - if [id1, id2] in dev_ids: - dev_fh.write("%s\t%s\t%s\t%s\t%s\n" % (label, id1, id2, s1, s2)) - else: - train_fh.write("%s\t%s\t%s\t%s\t%s\n" % (label, id1, id2, s1, s2)) - - with open(mrpc_test_file, encoding="utf8") as data_fh, open( - os.path.join(mrpc_dir, "test.tsv"), "w", encoding="utf8" - ) as test_fh: - header = data_fh.readline() - test_fh.write("index\t#1 ID\t#2 ID\t#1 String\t#2 String\n") - for idx, row in enumerate(data_fh): - label, id1, id2, s1, s2 = row.strip().split("\t") - test_fh.write("%d\t%s\t%s\t%s\t%s\n" % (idx, id1, id2, s1, s2)) - print("\tCompleted!") - - -def download_diagnostic(data_dir): - print("Downloading and extracting diagnostic data...") - if not os.path.isdir(os.path.join(data_dir, "MNLI")): - os.mkdir(os.path.join(data_dir, "MNLI")) - data_file = os.path.join(data_dir, "MNLI", "diagnostic.tsv") - urllib.request.urlretrieve(TASK2PATH["diagnostic"][0], data_file) - data_file = os.path.join(data_dir, "MNLI", "diagnostic-full.tsv") - urllib.request.urlretrieve(TASK2PATH["diagnostic"][1], data_file) - print("\tCompleted!") - return - - -def get_tasks(task_names): - task_names = task_names.split(",") - if "all" in task_names: - tasks = TASKS - else: - tasks = [] - for task_name in task_names: - assert task_name in TASKS, "Task %s not found!" % task_name - tasks.append(task_name) - if "MNLI" in tasks and "diagnostic" not in tasks: - tasks.append("diagnostic") - - return tasks - - -def main(arguments): - parser = argparse.ArgumentParser() - parser.add_argument( - "--data_dir", help="directory to save data to", type=str, default="glue_data" - ) - parser.add_argument( - "--tasks", - help="tasks to download data for as a comma separated string", - type=str, - default="all", - ) - parser.add_argument( - "--path_to_mrpc", - help="path to directory containing extracted MRPC data, msr_paraphrase_train.txt and " - "msr_paraphrase_text.txt", - type=str, - default="", - ) - args = parser.parse_args(arguments) - - if not os.path.isdir(args.data_dir): - os.mkdir(args.data_dir) - tasks = get_tasks(args.tasks) - - for task in tasks: - if task == "MRPC": - format_mrpc(args.data_dir, args.path_to_mrpc) - elif task == "diagnostic": - download_diagnostic(args.data_dir) - else: - download_and_extract(task, args.data_dir) - - -if __name__ == "__main__": - sys.exit(main(sys.argv[1:])) diff --git a/scripts/download_superglue_data.py b/scripts/download_superglue_data.py deleted file mode 100755 index 7e3ce6808..000000000 --- a/scripts/download_superglue_data.py +++ /dev/null @@ -1,115 +0,0 @@ -#!/usr/bin/env python3 - -""" Script for downloading all SuperGLUE data. - -For licence information, see the original dataset information links -available from: https://super.gluebenchmark.com/ - -Example usage: - python download_superglue_data.py --data_dir data --tasks all - -""" - -import os -import sys -import shutil -import tempfile -import argparse -import urllib.request -import zipfile - -TASKS = ["CB", "COPA", "MultiRC", "RTE", "WiC", "WSC", "BoolQ", "ReCoRD", "diagnostic"] -TASK2PATH = { - "CB": "https://dl.fbaipublicfiles.com/glue/superglue/data/v2/CB.zip", - "COPA": "https://dl.fbaipublicfiles.com/glue/superglue/data/v2/COPA.zip", - "MultiRC": "https://dl.fbaipublicfiles.com/glue/superglue/data/v2/MultiRC.zip", - "RTE": "https://dl.fbaipublicfiles.com/glue/superglue/data/v2/RTE.zip", - "WiC": "https://dl.fbaipublicfiles.com/glue/superglue/data/v2/WiC.zip", - "WSC": "https://dl.fbaipublicfiles.com/glue/superglue/data/v2/WSC.zip", - "broadcoverage-diagnostic": "https://dl.fbaipublicfiles.com/glue/superglue/data/v2/AX-b.zip", - "winogender-diagnostic": "https://dl.fbaipublicfiles.com/glue/superglue/data/v2/AX-g.zip", - "BoolQ": "https://dl.fbaipublicfiles.com/glue/superglue/data/v2/BoolQ.zip", - "ReCoRD": "https://dl.fbaipublicfiles.com/glue/superglue/data/v2/ReCoRD.zip", -} - - -def download_and_extract(task, data_dir): - print("Downloading and extracting %s..." % task) - if not os.path.isdir(data_dir): - os.mkdir(data_dir) - data_file = os.path.join(data_dir, "%s.zip" % task) - urllib.request.urlretrieve(TASK2PATH[task], data_file) - with zipfile.ZipFile(data_file) as zip_ref: - zip_ref.extractall(data_dir) - os.remove(data_file) - print(f"\tCompleted! Downloaded {task} data to directory {data_dir}") - - -def download_diagnostic(data_dir): - print("Downloading and extracting diagnostic...") - if not os.path.isdir(os.path.join(data_dir, "RTE")): - os.mkdir(os.path.join(data_dir, "RTE")) - diagnostic_dir = os.path.join(data_dir, "RTE", "diagnostics") - if not os.path.isdir(diagnostic_dir): - os.mkdir(diagnostic_dir) - - data_file = os.path.join(diagnostic_dir, "broadcoverage.zip") - urllib.request.urlretrieve(TASK2PATH["broadcoverage-diagnostic"], data_file) - with zipfile.ZipFile(data_file) as zip_ref: - zip_ref.extractall(diagnostic_dir) - shutil.move(os.path.join(diagnostic_dir, "AX-b", "AX-b.jsonl"), diagnostic_dir) - os.rmdir(os.path.join(diagnostic_dir, "AX-b")) - os.remove(data_file) - - data_file = os.path.join(diagnostic_dir, "winogender.zip") - urllib.request.urlretrieve(TASK2PATH["winogender-diagnostic"], data_file) - with zipfile.ZipFile(data_file) as zip_ref: - zip_ref.extractall(diagnostic_dir) - shutil.move(os.path.join(diagnostic_dir, "AX-g", "AX-g.jsonl"), diagnostic_dir) - os.rmdir(os.path.join(diagnostic_dir, "AX-g")) - os.remove(data_file) - print("\tCompleted!") - return - - -def get_tasks(task_names): - task_names = task_names.split(",") - if "all" in task_names: - tasks = TASKS - else: - tasks = [] - for task_name in task_names: - assert task_name in TASKS, "Task %s not found!" % task_name - tasks.append(task_name) - if "RTE" in tasks and "diagnostic" not in tasks: - tasks.append("diagnostic") - return tasks - - -def main(arguments): - parser = argparse.ArgumentParser() - parser.add_argument( - "-d", "--data_dir", help="directory to save data to", type=str, default="../superglue_data" - ) - parser.add_argument( - "-t", - "--tasks", - help="tasks to download data for as a comma separated string", - type=str, - default="all", - ) - args = parser.parse_args(arguments) - - if not os.path.exists(args.data_dir): - os.mkdir(args.data_dir) - tasks = get_tasks(args.tasks) - - for task in tasks: - if task == "diagnostic": - download_diagnostic(args.data_dir) - else: - download_and_extract(task, args.data_dir) - - -if __name__ == "__main__": - sys.exit(main(sys.argv[1:])) diff --git a/scripts/edgeprobing/analyze_project.sh b/scripts/edgeprobing/analyze_project.sh deleted file mode 100755 index d4c54056d..000000000 --- a/scripts/edgeprobing/analyze_project.sh +++ /dev/null @@ -1,48 +0,0 @@ -#!/bin/bash - -# Convenience script to analyze a directory ("project") of experiments. -# -# Usage: ./analyze_project.sh /path/to/project -# -# Expected directory structure: -# / -# / -# run/ -# vocab/ -# / -# run/ -# vocab/ -# (...) -# -# Will create /scores.tsv and /scalars.tsv as output. - -PROJECT_DIR=$1 - -set -eu - -if [ -z $PROJECT_DIR ]; then - echo "You must provide a project directory!" - exit 1 -fi - -THIS_DIR=$(realpath $(dirname $0)) -JIANT_DIR=${THIS_DIR%jiant*}/jiant - -all_runs=( ${PROJECT_DIR}/*/run* ) -echo "Found runs:" -for run in "${all_runs[@]}"; do - echo $run -done - -nproc=$( grep -c ^processor /proc/cpuinfo ) -nparallel=$( expr $nproc - 1 ) - -set -x - -python $JIANT_DIR/probing/analyze_runs.py \ - -i "${all_runs[@]}" -o ${PROJECT_DIR}/scores.tsv \ - --parallel $(( $nparallel > 10 ? 10 : $nparallel )) - -python $JIANT_DIR/probing/get_scalar_mix.py \ - -i "${all_runs[@]}" -o ${PROJECT_DIR}/scalars.tsv - diff --git a/scripts/edgeprobing/example_probe_existing.sh b/scripts/edgeprobing/example_probe_existing.sh deleted file mode 100755 index df65efb95..000000000 --- a/scripts/edgeprobing/example_probe_existing.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/bin/bash - -# Script to run an edge-probing task on an existing trained model. -# Based on prob_example_run.sh - -# NOTE: don't be startled if you see a lot of warnings about missing parameters, -# like: -# Parameter missing from checkpoint: edges-srl-conll2005_mdl.proj2.weight -# This is normal, because the probing task won't be in the original checkpoint. - -MODEL_DIR=$1 # directory of checkpoint to probe, - # e.g: /nfs/jsalt/share/models_to_probe/nli_do2_noelmo -PROBING_TASK=${2:-"edges-spr2"} # probing task name(s) - -EXP_NAME=${3:-"edgeprobe-$(basename $MODEL_DIR)"} # experiment name -RUN_NAME=${4:-"probing"} # name for this run - -PARAM_FILE=${MODEL_DIR}"/params.conf" -MODEL_FILE=${MODEL_DIR}"/model_state_eval_best.th" - -OVERRIDES="load_eval_checkpoint = ${MODEL_FILE}" -OVERRIDES+=", exp_name = ${EXP_NAME}" -OVERRIDES+=", run_name = ${RUN_NAME}" -OVERRIDES+=", target_tasks = ${PROBING_TASK}" - -pushd "${PWD%jiant*}jiant" - -# Load defaults.conf for any missing params, then model param file, -# then eval_existing.conf to override paths & eval config. -# Finally, apply custom overrides defined above. -# To add email notifications, add an additional argument: -# --notify my_email@example.com -python main.py -c jiant/config/defaults.conf ${PARAM_FILE} jiant/config/edgeprobe/edgeprobe_existing.conf \ - -o "${OVERRIDES}" --remote_log diff --git a/scripts/edgeprobing/exp_fns.sh b/scripts/edgeprobing/exp_fns.sh deleted file mode 100644 index 25d73fda4..000000000 --- a/scripts/edgeprobing/exp_fns.sh +++ /dev/null @@ -1,211 +0,0 @@ -#!/bin/bash - -# Library of experiment functions for running main edge-probing experiments. -# Don't execute this script directly, but instead include at the top of an -# experiment script as: -# -# export NOTIFY_EMAIL="yourname@gmail.com" # optional, only works with creds -# pushd /path/to/jiant -# source scripts/edges/exp_fns.sh -# elmo_chars_exp edges-srl-conll2012 -# elmo_full_exp edges-srl-conll2012 -# elmo_ortho_exp edges-srl-conll2012 0 -# -# -# See individual functions below for usage. - -EP_RESOURCE_DIR="/nfs/jiant/share/edge-probing/resources" - -function run_exp() { - # Helper function to invoke main.py. - # Don't run this directly - use the experiment functions below, - # or create a new one for a new experiment suite. - # Usage: run_exp - CONFIG_FILE=$1 - OVERRIDES=$2 - declare -a args - args+=( --config_file "${CONFIG_FILE}" ) - args+=( -o "${OVERRIDES}" --remote_log ) - if [ ! -z $NOTIFY_EMAIL ]; then - args+=( --notify "$NOTIFY_EMAIL" ) - fi - python main.py "${args[@]}" -} - -function elmo_chars_exp() { - # Lexical baseline, probe ELMo char CNN layer. - # Usage: elmo_chars_exp - OVERRIDES="exp_name=elmo-chars-$1, run_name=run" - OVERRIDES+=", target_tasks=$1, input_module=elmo-chars-only" - run_exp "jiant/config/edgeprobe/edgeprobe_bare.conf" "${OVERRIDES}" -} - -function elmo_full_exp() { - # Full ELMo, probe full ELMo with learned mixing weights. - # Usage: elmo_full_exp - OVERRIDES="exp_name=elmo-full-$1, run_name=run" - OVERRIDES+=", target_tasks=$1, input_module=elmo" - run_exp "jiant/config/edgeprobe/edgeprobe_bare.conf" "${OVERRIDES}" -} - -function elmo_ortho_exp() { - # Full ELMo with random orthogonal weights for LSTM and projections. - # Usage: elmo_ortho_exp - ELMO_WEIGHTS_PATH="${EP_RESOURCE_DIR}/random_elmo/elmo_2x4096_512_2048cnn_2xhighway_weights_ortho_seed_$2.hdf5" - OVERRIDES="exp_name=elmo-ortho-$1, run_name=run_seed_$2" - OVERRIDES+=", target_tasks=$1, input_module=elmo" - OVERRIDES+=", elmo_weight_file_path=${ELMO_WEIGHTS_PATH}" - run_exp "jiant/config/edgeprobe/edgeprobe_bare.conf" "${OVERRIDES}" -} - -function elmo_random_exp() { - # Full ELMo with random normal weights for LSTM and projections. - # Usage: elmo_random_exp - ELMO_WEIGHTS_PATH="${EP_RESOURCE_DIR}/random_elmo/elmo_2x4096_512_2048cnn_2xhighway_weights_random_seed_$2.hdf5" - OVERRIDES="exp_name=elmo-random-$1, run_name=run_seed_$2" - OVERRIDES+=", target_tasks=$1, input_module=elmo" - OVERRIDES+=", elmo_weight_file_path=${ELMO_WEIGHTS_PATH}" - run_exp "jiant/config/edgeprobe/edgeprobe_bare.conf" "${OVERRIDES}" -} - -function train_chars_exp() { - # Trained encoder over ELMo character layer. - # Usage: train_chars_exp - OVERRIDES="exp_name=train-chars-$1, run_name=run" - OVERRIDES+=", pretrain_tasks=$1, max_vals=$2, val_interval=$3" - OVERRIDES+=", input_module=elmo-chars-only" - run_exp "jiant/config/edgeprobe/edgeprobe_train.conf" "${OVERRIDES}" -} - -function train_full_exp() { - # Trained encoder over full ELMo. - # Usage: train_full_exp - OVERRIDES="exp_name=train-full-$1, run_name=run" - OVERRIDES+=", pretrain_tasks=$1, max_vals=$2, val_interval=$3" - OVERRIDES+=", input_module=elmo" - run_exp "jiant/config/edgeprobe/edgeprobe_train.conf" "${OVERRIDES}" -} - -## -# GloVe and CoVe-based models. -function glove_exp() { - # Lexical baseline, probe GloVe embeddings. - # Usage: glove_exp - OVERRIDES="exp_name=glove-$1, run_name=run" - OVERRIDES+=", target_tasks=$1" - run_exp "jiant/config/edgeprobe/edgeprobe_glove.conf" "${OVERRIDES}" -} - -function cove_exp() { - # Probe CoVe, which is concatenated with GloVe per standard usage. - # Usage: cove_exp - OVERRIDES="exp_name=cove-$1, run_name=run" - OVERRIDES+=", target_tasks=$1" - run_exp "jiant/config/edgeprobe/edgeprobe_cove.conf" "${OVERRIDES}" -} - -## -# OpenAI transformer model. -function openai_exp() { - # Probe the OpenAI transformer model. - # Usage: openai_exp - OVERRIDES="exp_name=openai-$1, run_name=run" - OVERRIDES+=", target_tasks=$1" - run_exp "jiant/config/edgeprobe/edgeprobe_openai.conf" "${OVERRIDES}" -} - -function openai_cat_exp() { - # As above, but concat embeddings to output. - # Usage: openai_cat_exp - OVERRIDES="exp_name=openai-cat-$1, run_name=run" - OVERRIDES+=", target_tasks=$1" - OVERRIDES+=", openai_output_mode=cat" - run_exp "jiant/config/edgeprobe/edgeprobe_openai.conf" "${OVERRIDES}" -} - -function openai_lex_exp() { - # Probe the OpenAI transformer model base layer. - # Usage: openai_lex_exp - OVERRIDES="exp_name=openai-lex-$1, run_name=run" - OVERRIDES+=", target_tasks=$1" - OVERRIDES+=", openai_output_mode=only" - run_exp "jiant/config/edgeprobe/edgeprobe_openai.conf" "${OVERRIDES}" -} - -function openai_mix_exp() { - # Probe the OpenAI transformer with ELMo-style scalar mixing across layers. - # Usage: openai_mix_exp - OVERRIDES="exp_name=openai-mix-$1, run_name=run" - OVERRIDES+=", target_tasks=$1" - OVERRIDES+=", openai_output_mode=mix" - run_exp "jiant/config/edgeprobe/edgeprobe_openai.conf" "${OVERRIDES}" -} - -function openai_bwb_exp() { - # Probe the OpenAI transformer model, as trained on BWB-shuffled. - # Usage: openai_bwb_exp - CKPT_PATH="${EP_RESOURCE_DIR}/checkpoints/bwb_shuffled/model.ckpt-1000000" - OVERRIDES="exp_name=openai-bwb-$1, run_name=run" - OVERRIDES+=", target_tasks=$1" - OVERRIDES+=", openai_transformer_ckpt=${CKPT_PATH}" - OVERRIDES+=", openai_output_mode=cat" - run_exp "jiant/config/edgeprobe/edgeprobe_openai.conf" "${OVERRIDES}" -} - -## -# BERT model. -# These take two arguments: the task name, and the bert model -# (e.g. base-uncased) -function bert_cat_exp() { - # Run BERT, and concat embeddings to output. - # Usage: bert_cat_exp - OVERRIDES="exp_name=bert-${2}-cat-${1}, run_name=run" - OVERRIDES+=", target_tasks=$1" - OVERRIDES+=", input_module=bert-$2" - OVERRIDES+=", transformers_output_mode=cat" - run_exp "jiant/config/edgeprobe/edgeprobe_bert.conf" "${OVERRIDES}" -} - -function bert_lex_exp() { - # Probe the BERT token embeddings. - # Usage: bert_lex_exp - OVERRIDES="exp_name=bert-${2}-lex-${1}, run_name=run" - OVERRIDES+=", target_tasks=$1" - OVERRIDES+=", input_module=bert-$2" - OVERRIDES+=", transformers_output_mode=only" - run_exp "jiant/config/edgeprobe/edgeprobe_bert.conf" "${OVERRIDES}" -} - -function bert_mix_exp() { - # Run BERT with ELMo-style scalar mixing across layers. - # Usage: bert_mix_exp - OVERRIDES="exp_name=bert-${2}-mix-${1}, run_name=run" - OVERRIDES+=", target_tasks=$1" - OVERRIDES+=", input_module=bert-$2" - OVERRIDES+=", transformers_output_mode=mix" - run_exp "jiant/config/edgeprobe/edgeprobe_bert.conf" "${OVERRIDES}" -} - -## -# BERT layer experiments, for ACL paper -function bert_mix_k_exp() { - # Run BERT with ELMo-style scalar mixing across the first K layers. - # Usage: bert_mix_k_exp - OVERRIDES="exp_name=bert-${2}-mix_${3}-${1}, run_name=run" - OVERRIDES+=", target_tasks=$1" - OVERRIDES+=", input_module=bert-$2" - OVERRIDES+=", transformers_output_mode=mix" - OVERRIDES+=", transformers_max_layer=${3}" - run_exp "jiant/config/edgeprobe/edgeprobe_bert.conf" "${OVERRIDES}" -} - -function bert_at_k_exp() { - # Run BERT and probe layer K. - # Usage: bert_at_k_exp - OVERRIDES="exp_name=bert-${2}-at_${3}-${1}, run_name=run" - OVERRIDES+=", target_tasks=$1" - OVERRIDES+=", input_module=bert-$2" - OVERRIDES+=", transformers_output_mode=top" - OVERRIDES+=", transformers_max_layer=${3}" - run_exp "jiant/config/edgeprobe/edgeprobe_bert.conf" "${OVERRIDES}" -} diff --git a/scripts/edgeprobing/kubernetes_run_all.sh b/scripts/edgeprobing/kubernetes_run_all.sh deleted file mode 100755 index 10a7f81d8..000000000 --- a/scripts/edgeprobing/kubernetes_run_all.sh +++ /dev/null @@ -1,185 +0,0 @@ -#!/bin/bash - -# Master script to start a full suite of edge probing experiments on -# on Kubernetes. Comment out lines below to run only a subset of experiments. -# -# Usage: -# ./scripts/edgeprobing/kubernetes_run_all.sh -p -# -# To run on a particular cluster, authenticate to that cluster with: -# gcloud container clusters get-credentials --zone -# -# This is mostly a wrapper around gcp/kubernetes/run_batch.sh. It constructs -# command lines that use the pre-set experiment functions defined in -# exp_fns.sh, and calls run_batch.sh to start jobs. See exp_fns.sh for the -# override params, and jiant/config/edgeprobe/edgeprobe_*.conf for the base -# configs. -# -# In addition to starting jobs, this script copies the current jiant/ repo to -# the project folder. This serves as a record of the code used for a particular -# set of experiments. The jobs will run jiant from this copy, so you can safely -# continue to work in your local repo without affecting the experiments. - -set -e - -# Default arguments. -PROJECT_NAME="" -NOTIFY_EMAIL="$NOTIFY_EMAIL" # allow pre-set from shell - -# Handle flags. -OPTIND=1 # Reset in case getopts has been used previously in the shell. -while getopts ":p:n:" opt; do - case "$opt" in - p) PROJECT_NAME=$OPTARG - ;; - n) NOTIFY_EMAIL=$OPTARG - ;; - \? ) - echo "Invalid flag $opt." - exit 1 - ;; - esac -done -shift $((OPTIND-1)) - -# Remaining positional arguments. -MODE=${1:-"create"} - -if [ -z $PROJECT_NAME ]; then - echo "You must provide a project name!" - exit 1 -fi - -if [ -z $NOTIFY_EMAIL ]; then - echo "You must provide an email address!" - exit 1 -fi - -# Top-level directory for the current repo. -pushd $(git rev-parse --show-toplevel) - -# Get the NFS path from the Kubernetes config, so that it doesn't need to be -# hardcoded here. -pushd gcp/kubernetes/templates -NFS_EXP_DIR=$(jsonnet -S -e "local env = import 'jiant_env.libsonnet'; env.nfs_exp_dir") -echo "Assuming NFS experiment path at $NFS_EXP_DIR" -popd - -# Make a copy of the current tree in the project directory. -PROJECT_DIR="${NFS_EXP_DIR}/${USER}/${PROJECT_NAME}" -if [ ! -d "${NFS_EXP_DIR}/$USER" ]; then - mkdir "${NFS_EXP_DIR}/$USER" -fi -if [ ! -d "${PROJECT_DIR}" ]; then - echo "Creating project directory ${PROJECT_DIR}" - mkdir ${PROJECT_DIR} - chmod -R o+w ${PROJECT_DIR} -fi -if [[ $MODE != "delete" ]]; then - echo "Copying source tree to project dir..." - rsync -a --exclude=".git" "./" "${PROJECT_DIR}/jiant" -fi -PATH_TO_JIANT="${PROJECT_DIR}/jiant" - -function make_kubernetes_command() { - # Generate shell command to execute in container. - # Uses exp_fns.sh to generate configs; see that file for details - # and to define new experiments. - echo -n "pushd ${PATH_TO_JIANT}" - echo -n "; source scripts/edgeprobing/exp_fns.sh" - echo -n "; $@" -} - -function kuberun() { - # Create a Kubernetes job using run_batch.sh - NAME=$1 - COMMAND=$(make_kubernetes_command $2) - echo "Job '$NAME': '$COMMAND'" - ./gcp/kubernetes/run_batch.sh -m $MODE -p ${PROJECT_NAME} -g ${GPU_TYPE} \ - $NAME "$COMMAND" - # -n ${NOTIFY_EMAIL} \ # Temporarily disabled - echo "" -} - -## -# All experiments below. -# Uncomment the lines you want to run, or comment out those you don't. -## - -declare -a ALL_TASKS -ALL_TASKS+=( "spr1" ) -ALL_TASKS+=( "spr2" ) -ALL_TASKS+=( "dpr" ) -ALL_TASKS+=( "dep-ud-ewt" ) -ALL_TASKS+=( "nonterminal-ontonotes" ) -ALL_TASKS+=( "pos-ontonotes" ) -ALL_TASKS+=( "ner-ontonotes" ) -ALL_TASKS+=( "srl-ontonotes" ) -ALL_TASKS+=( "coref-ontonotes" ) -ALL_TASKS+=( "rel-semeval" ) -echo "All tasks to run: ${ALL_TASKS[@]}" - -if [[ $MODE == "delete" ]]; then - # OK to fail to delete some jobs, still try others. - set +e -fi - -## -# Experiments for the ICLR paper ("edge probing paper"), comparing different -# encoders. - -## -# Run these on p100s (default) -export GPU_TYPE="p100" -for task in "${ALL_TASKS[@]}" -do - # ELMo is currently broken at master, so skip these. - # kuberun elmo-chars-$task "elmo_chars_exp edges-$task" - # kuberun elmo-ortho-$task "elmo_ortho_exp edges-$task 0" - # kuberun elmo-full-$task "elmo_full_exp edges-$task" - kuberun glove-$task "glove_exp edges-$task" - kuberun cove-$task "cove_exp edges-$task" - - kuberun openai-lex-$task "openai_lex_exp edges-$task" - kuberun bert-base-uncased-lex-$task "bert_lex_exp edges-$task base-uncased" - kuberun bert-large-uncased-lex-$task "bert_lex_exp edges-$task large-uncased" -done - -## -# Run the larger experiments (transformers) on v100s -export GPU_TYPE="v100" -for task in "${ALL_TASKS[@]}" -do - kuberun openai-cat-$task "openai_cat_exp edges-$task" - kuberun openai-mix-$task "openai_mix_exp edges-$task" - kuberun openai-bwb-$task "openai_bwb_exp edges-$task" - - kuberun bert-base-uncased-cat-$task "bert_cat_exp edges-$task base-uncased" - kuberun bert-large-uncased-cat-$task "bert_cat_exp edges-$task large-uncased" - - # BERT with ELMo-style scalar mixing. - kuberun bert-base-uncased-mix-$task "bert_mix_exp edges-$task base-uncased" - kuberun bert-large-uncased-mix-$task "bert_mix_exp edges-$task large-uncased" -done - -## -# Experiments for the ACL paper ("BERT layer paper"), comparing the different -# layers of BERT. -export GPU_TYPE="p100" -for task in "${ALL_TASKS[@]}" -do - # Probe BERT-base - for k in $(seq -f "%02.f" 0 12); do - kuberun bert-base-uncased-at-${k}-$task "bert_at_k_exp edges-$task base-uncased ${k}" - kuberun bert-base-uncased-mix-${k}-$task "bert_mix_k_exp edges-$task base-uncased ${k}" - done -done -export GPU_TYPE="v100" -for task in "${ALL_TASKS[@]}" -do - # Probe BERT-large - for k in $(seq-f "%02.f" 0 24); do - kuberun bert-large-uncased-at-${k}-$task "bert_at_k_exp edges-$task large-uncased ${k}" - kuberun bert-large-uncased-mix-${k}-$task "bert_mix_k_exp edges-$task large-uncased ${k}" - done -done diff --git a/scripts/example_result.txt b/scripts/example_result.txt deleted file mode 100644 index 2e0b78c38..000000000 --- a/scripts/example_result.txt +++ /dev/null @@ -1,4 +0,0 @@ -# Includes an example before and after Jan's naming change. -noelmo-do4-sd1 micro_avg: 0.680, macro_avg: 0.340, mnli_accuracy: 0.680, mnli-diagnostic_accuracy: 0.000, mnli-diagnostic_lex_sem__Morphological negation: 0.413, mnli-diagnostic_lex_sem__Lexical entailment: 0.061, mnli-diagnostic_lex_sem__Quantifiers: 0.349, mnli-diagnostic_lex_sem__Redundancy: 0.693, mnli-diagnostic_lex_sem__Symmetry.Collectivity: 0.000, mnli-diagnostic_lex_sem__Named entities: 0.000, mnli-diagnostic_lex_sem__Factivity: 0.044, mnli-diagnostic_lex_sem__missing: 0.188, mnli-diagnostic_pr_ar_str__Anaphora.Coreference: 0.263, mnli-diagnostic_pr_ar_str__Intersectivity: 0.000, mnli-diagnostic_pr_ar_str__Nominalization: 0.000, mnli-diagnostic_pr_ar_str__Active.Passive: 0.397, mnli-diagnostic_pr_ar_str__Prepositional phrases: 0.181, mnli-diagnostic_pr_ar_str__Genitives.Partitives: 0.687, mnli-diagnostic_pr_ar_str__Core args: 0.125, mnli-diagnostic_pr_ar_str__Relative clauses: 0.188, mnli-diagnostic_pr_ar_str__Coordination scope: 0.204, mnli-diagnostic_pr_ar_str__Restrictivity: -0.146, mnli-diagnostic_pr_ar_str__Datives: 0.556, mnli-diagnostic_pr_ar_str__Ellipsis.Implicits: 0.244, mnli-diagnostic_pr_ar_str__missing: 0.225, mnli-diagnostic_logic__Negation: -0.060, mnli-diagnostic_logic__Conditionals: -0.008, mnli-diagnostic_logic__Double negation: -0.224, mnli-diagnostic_logic__Upward monotone: 0.000, mnli-diagnostic_logic__Downward monotone: 0.117, mnli-diagnostic_logic__Intervals.Numbers: 0.123, mnli-diagnostic_logic__Conjunction: 0.360, mnli-diagnostic_logic__Disjunction: -0.193, mnli-diagnostic_logic__Universal: 0.697, mnli-diagnostic_logic__Existential: 0.249, mnli-diagnostic_logic__Temporal: -0.156, mnli-diagnostic_logic__Non-monotone: -0.057, mnli-diagnostic_logic__missing: 0.120, mnli-diagnostic_knowledge__World knowledge: 0.097, mnli-diagnostic_knowledge__Common sense: 0.150, mnli-diagnostic_knowledge__missing: 0.137 -elmo-do4-sd1 micro_avg: 0.000, macro_avg: 0.000, mnli-diagnostic_accuracy: 0.000, mnli-diagnostic_lex_sem__Morphological negation: 0.000, mnli-diagnostic_lex_sem__Lexical entailment: 0.000, mnli-diagnostic_lex_sem__Quantifiers: 0.000, mnli-diagnostic_lex_sem__Redundancy: 0.000, mnli-diagnostic_lex_sem__Symmetry/Collectivity: 0.000, mnli-diagnostic_lex_sem__Named entities: 0.000, mnli-diagnostic_lex_sem__Factivity: 0.000, mnli-diagnostic_lex_sem: 0.000, mnli-diagnostic_pr_ar_str__Anaphora/Coreference: 0.000, mnli-diagnostic_pr_ar_str__Intersectivity: 0.000, mnli-diagnostic_pr_ar_str__Nominalization: 0.000, mnli-diagnostic_pr_ar_str__Active/Passive: 0.000, mnli-diagnostic_pr_ar_str__Prepositional phrases: 0.000, mnli-diagnostic_pr_ar_str__Genitives/Partitives: 0.000, mnli-diagnostic_pr_ar_str__Core args: 0.000, mnli-diagnostic_pr_ar_str__Relative clauses: 0.000, mnli-diagnostic_pr_ar_str__Coordination scope: 0.000, mnli-diagnostic_pr_ar_str__Restrictivity: 0.000, mnli-diagnostic_pr_ar_str__Datives: 0.000, mnli-diagnostic_pr_ar_str__Ellipsis/Implicits: 0.000, mnli-diagnostic_pr_ar_str: 0.000, mnli-diagnostic_logic__Negation: 0.000, mnli-diagnostic_logic__Conditionals: 0.000, mnli-diagnostic_logic__Double negation: 0.000, mnli-diagnostic_logic__Upward monotone: 0.000, mnli-diagnostic_logic__Downward monotone: 0.000, mnli-diagnostic_logic__Intervals/Numbers: 0.000, mnli-diagnostic_logic__Conjunction: 0.000, mnli-diagnostic_logic__Disjunction: 0.000, mnli-diagnostic_logic__Universal: 0.000, mnli-diagnostic_logic__Existential: 0.000, mnli-diagnostic_logic__Temporal: 0.000, mnli-diagnostic_logic__Non-monotone: 0.000, mnli-diagnostic_logic: 0.000, mnli-diagnostic_knowledge__World knowledge: 0.000, mnli-diagnostic_knowledge__Common sense: 0.000, mnli-diagnostic_knowledge: 0.000 - diff --git a/scripts/example_run/results.tsv b/scripts/example_run/results.tsv deleted file mode 100644 index 2e0b78c38..000000000 --- a/scripts/example_run/results.tsv +++ /dev/null @@ -1,4 +0,0 @@ -# Includes an example before and after Jan's naming change. -noelmo-do4-sd1 micro_avg: 0.680, macro_avg: 0.340, mnli_accuracy: 0.680, mnli-diagnostic_accuracy: 0.000, mnli-diagnostic_lex_sem__Morphological negation: 0.413, mnli-diagnostic_lex_sem__Lexical entailment: 0.061, mnli-diagnostic_lex_sem__Quantifiers: 0.349, mnli-diagnostic_lex_sem__Redundancy: 0.693, mnli-diagnostic_lex_sem__Symmetry.Collectivity: 0.000, mnli-diagnostic_lex_sem__Named entities: 0.000, mnli-diagnostic_lex_sem__Factivity: 0.044, mnli-diagnostic_lex_sem__missing: 0.188, mnli-diagnostic_pr_ar_str__Anaphora.Coreference: 0.263, mnli-diagnostic_pr_ar_str__Intersectivity: 0.000, mnli-diagnostic_pr_ar_str__Nominalization: 0.000, mnli-diagnostic_pr_ar_str__Active.Passive: 0.397, mnli-diagnostic_pr_ar_str__Prepositional phrases: 0.181, mnli-diagnostic_pr_ar_str__Genitives.Partitives: 0.687, mnli-diagnostic_pr_ar_str__Core args: 0.125, mnli-diagnostic_pr_ar_str__Relative clauses: 0.188, mnli-diagnostic_pr_ar_str__Coordination scope: 0.204, mnli-diagnostic_pr_ar_str__Restrictivity: -0.146, mnli-diagnostic_pr_ar_str__Datives: 0.556, mnli-diagnostic_pr_ar_str__Ellipsis.Implicits: 0.244, mnli-diagnostic_pr_ar_str__missing: 0.225, mnli-diagnostic_logic__Negation: -0.060, mnli-diagnostic_logic__Conditionals: -0.008, mnli-diagnostic_logic__Double negation: -0.224, mnli-diagnostic_logic__Upward monotone: 0.000, mnli-diagnostic_logic__Downward monotone: 0.117, mnli-diagnostic_logic__Intervals.Numbers: 0.123, mnli-diagnostic_logic__Conjunction: 0.360, mnli-diagnostic_logic__Disjunction: -0.193, mnli-diagnostic_logic__Universal: 0.697, mnli-diagnostic_logic__Existential: 0.249, mnli-diagnostic_logic__Temporal: -0.156, mnli-diagnostic_logic__Non-monotone: -0.057, mnli-diagnostic_logic__missing: 0.120, mnli-diagnostic_knowledge__World knowledge: 0.097, mnli-diagnostic_knowledge__Common sense: 0.150, mnli-diagnostic_knowledge__missing: 0.137 -elmo-do4-sd1 micro_avg: 0.000, macro_avg: 0.000, mnli-diagnostic_accuracy: 0.000, mnli-diagnostic_lex_sem__Morphological negation: 0.000, mnli-diagnostic_lex_sem__Lexical entailment: 0.000, mnli-diagnostic_lex_sem__Quantifiers: 0.000, mnli-diagnostic_lex_sem__Redundancy: 0.000, mnli-diagnostic_lex_sem__Symmetry/Collectivity: 0.000, mnli-diagnostic_lex_sem__Named entities: 0.000, mnli-diagnostic_lex_sem__Factivity: 0.000, mnli-diagnostic_lex_sem: 0.000, mnli-diagnostic_pr_ar_str__Anaphora/Coreference: 0.000, mnli-diagnostic_pr_ar_str__Intersectivity: 0.000, mnli-diagnostic_pr_ar_str__Nominalization: 0.000, mnli-diagnostic_pr_ar_str__Active/Passive: 0.000, mnli-diagnostic_pr_ar_str__Prepositional phrases: 0.000, mnli-diagnostic_pr_ar_str__Genitives/Partitives: 0.000, mnli-diagnostic_pr_ar_str__Core args: 0.000, mnli-diagnostic_pr_ar_str__Relative clauses: 0.000, mnli-diagnostic_pr_ar_str__Coordination scope: 0.000, mnli-diagnostic_pr_ar_str__Restrictivity: 0.000, mnli-diagnostic_pr_ar_str__Datives: 0.000, mnli-diagnostic_pr_ar_str__Ellipsis/Implicits: 0.000, mnli-diagnostic_pr_ar_str: 0.000, mnli-diagnostic_logic__Negation: 0.000, mnli-diagnostic_logic__Conditionals: 0.000, mnli-diagnostic_logic__Double negation: 0.000, mnli-diagnostic_logic__Upward monotone: 0.000, mnli-diagnostic_logic__Downward monotone: 0.000, mnli-diagnostic_logic__Intervals/Numbers: 0.000, mnli-diagnostic_logic__Conjunction: 0.000, mnli-diagnostic_logic__Disjunction: 0.000, mnli-diagnostic_logic__Universal: 0.000, mnli-diagnostic_logic__Existential: 0.000, mnli-diagnostic_logic__Temporal: 0.000, mnli-diagnostic_logic__Non-monotone: 0.000, mnli-diagnostic_logic: 0.000, mnli-diagnostic_knowledge__World knowledge: 0.000, mnli-diagnostic_knowledge__Common sense: 0.000, mnli-diagnostic_knowledge: 0.000 - diff --git a/scripts/export_from_bash.sh b/scripts/export_from_bash.sh deleted file mode 100644 index 2db33f00a..000000000 --- a/scripts/export_from_bash.sh +++ /dev/null @@ -1,25 +0,0 @@ -# Running 'source scripts/export_from_bash.sh' from the base jiant/ dir will add the job of -# running user_config.sh directly to the bash startup script (bashrc for Linux and bash_profile for MacOS). - -function changebashpaths() { - output="source $(pwd)/user_config.sh" - case "$(uname -s)" in - Darwin) - echo $output >> ~/.bash_profile - source ~/.bash_profile - ;; - Linux) - echo $output >> ~/.bashrc - source ~/.bashrc - ;; - *) - echo 'Automatic path setup is only configured for MacOS and Linux.' - ;; - esac -} - -read -r -p "Are you sure you want to edit your bash configuration to set up jiant paths? (Y/N) " response -if [[ $response =~ ^[Yy]$ ]] - then - changebashpaths -fi diff --git a/scripts/mlm/README.md b/scripts/mlm/README.md deleted file mode 100644 index 7d0b9ab63..000000000 --- a/scripts/mlm/README.md +++ /dev/null @@ -1,21 +0,0 @@ -# Downloading Wikipedia Corpus - -We use the preprocessing code from https://github.com/NVIDIA/DeepLearningExamples/tree/master/PyTorch/LanguageModeling/BERT#getting-the-data -and the bash scripts provided here is used to help with streamlining the data generation in the NVIDIA repository. - -First, git clone https://github.com/NVIDIA/DeepLearningExamples.git. -Then, move create_wiki_data.sh and get_small_english_wiki.sh into DeepLearningExamples/PyTorch/LanguageModeling/BERT/data. - -Then, follow the instructions below: - -Run `bash create_wiki_data.sh $lang $save_directory` -The NVIDIA code supports English (en) and Chinese (zh) wikipedia. - -For example, to download and process English Wikipedia and save it in `~/Download` directory, run -`bash create_wiki_data.sh en ~/Download` - -The above command will download the entire English Wikipedia. - -In our experiments, we only use a small subset (around 5% of) the entire English Wikipedia, which has the same number of sentences as Wikitext103. -To get this subset, run `bash get_small_english_wiki.sh $path_to_wikicorpus_en`. where $path_to_wikicorpus_en is the directory where you saved the full processed `wikicorpus_en` corpus. - diff --git a/scripts/mlm/create_wiki_data.sh b/scripts/mlm/create_wiki_data.sh deleted file mode 100755 index 0f0722e24..000000000 --- a/scripts/mlm/create_wiki_data.sh +++ /dev/null @@ -1,49 +0,0 @@ -#!/bin/bash - -# Copyright (c) 2019 NVIDIA CORPORATION. All rights reserved. -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -lang=$1 #the language, 'en' for English wikipedia -export BERT_PREP_WORKING_DIR=$2 - -# clone wikiextractor if it doesn't exist -if [ ! -d "wikiextractor" ]; then - git clone https://github.com/attardi/wikiextractor.git -fi - -echo "Downloading $lang wikpedia in directory $save_dir" -# Download -python3 bertPrep.py --action download --dataset wikicorpus_$lang - - -# Properly format the text files -python3 bertPrep.py --action text_formatting --dataset wikicorpus_$lang - - -# Shard the text files (group wiki+books then shard) -python3 bertPrep.py --action sharding --dataset wikicorpus_$lang - - -# Combine sharded files into one -save_dir=$BERT_PREP_WORKING_DIR/sharded_training_shards_256_test_shards_256_fraction_0.2/wikicorpus_$lang -cat $save_dir/*training*.txt > $save_dir/train_$lang.txt -cat $save_dir/*test*.txt > $save_dir/test_$lang.txt -rm -rf $save_dir/wiki*training*.txt -rm -rf $save_dir/wiki*test*.txt - -# remove some remaining xml tags -sed -i 's/<[^>]*>//g' $save_dir/train_$lang.txt -sed -i 's/<[^>]*>//g' $save_dir/test_$lang.txt - -echo "Your corpus is saved in $save_dir" - diff --git a/scripts/mlm/get_small_english_wiki.sh b/scripts/mlm/get_small_english_wiki.sh deleted file mode 100644 index 81dd55097..000000000 --- a/scripts/mlm/get_small_english_wiki.sh +++ /dev/null @@ -1,6 +0,0 @@ -wiki_path=$1 - -mkdir -p $wiki_path/wikipedia_corpus_small -head -3978309 $wiki_path/train_en.txt > $wiki_path/wikipedia_corpus_small/train.txt -head -10001 $wiki_path/test_en.txt > $wiki_path/wikipedia_corpus_small/test.txt -tail -8438 $wiki_path/train_en.txt > $wiki_path/wikipedia_corpus_small/valid.txt diff --git a/scripts/move_preds_files.sh b/scripts/move_preds_files.sh deleted file mode 100644 index bdf74835a..000000000 --- a/scripts/move_preds_files.sh +++ /dev/null @@ -1,13 +0,0 @@ -FROM_DIR=$1 -TO_DIR=$2 - -cp ${FROM_DIR}/appear/nli-alt_val.tsv ${TO_DIR}/appear.tsv -cp ${FROM_DIR}/compare/nli-alt_val.tsv ${TO_DIR}/compare.tsv -cp ${FROM_DIR}/factives/nli-alt_val.tsv ${TO_DIR}/factives.tsv -cp ${FROM_DIR}/implicatives/nli-alt_val.tsv ${TO_DIR}/implicatives.tsv -cp ${FROM_DIR}/negation/nli-prob-negation_val.tsv ${TO_DIR}/negation.tsv -cp ${FROM_DIR}/neutrals/nli-alt_val.tsv ${TO_DIR}/neutrals.tsv -cp ${FROM_DIR}/nps_final/nps_val.tsv ${TO_DIR}/nps.tsv -cp ${FROM_DIR}/prepswap/nli-prob-prepswap_val.tsv ${TO_DIR}/prepswap.tsv -cp ${FROM_DIR}/quant/nli-alt_val.tsv ${TO_DIR}/quant.tsv -cp ${FROM_DIR}/spatial/nli-alt_val.tsv ${TO_DIR}/spatial.tsv diff --git a/scripts/nyu_cilvr_cluster.sbatch b/scripts/nyu_cilvr_cluster.sbatch deleted file mode 100644 index 435cf7aed..000000000 --- a/scripts/nyu_cilvr_cluster.sbatch +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/bash - -# Generic job script for all experiments on NYU CILVR machines. -# If you're using a SLURM-managed cluster, modify this to suit your environment. - -#SBATCH --gres=gpu:1 -#SBATCH --mem=30000 -#SBATCH --constraint=gpu_12gb,pascal - -# Example usage: -# JIANT_OVERRIDES="exp_name = main-multi-task-glue, pretrain_tasks = glue, run_name = noelmo-do2-sd1, elmo_chars_only = 1, dropout = 0.2" JIANT_CONF="jiant/config/defaults.conf" sbatch ../nyu_cilvr_cluster.sbatch - -# Log what we're running and where. -echo $SLURM_JOBID - `hostname` - $JIANT_OVERRIDES >> ~/jiant_machine_assignments.txt - -# Run. -cd ~/jiant/ -source user_config.sh -python main.py --config_file $JIANT_CONF --overrides "global_ro_exp_dir = /misc/vlgscratch4/BowmanGroup/sbowman/exp/default, project_dir = $JIANT_PROJECT_PREFIX, $JIANT_OVERRIDES" diff --git a/scripts/preprocess_senteval_probing.py b/scripts/preprocess_senteval_probing.py deleted file mode 100644 index 3b953d27b..000000000 --- a/scripts/preprocess_senteval_probing.py +++ /dev/null @@ -1,33 +0,0 @@ -""" - Splits senteval probing task into a train-val-test split - Usage: - python preprocess_senteval_probing.py --senteval_probing_path={path/to/senteval/probing/data} -""" -import os -import argparse -import pandas as pd - - -def parse_senteval_probing(args): - files = [x for x in os.listdir(args.senteval_probing_path) if "txt" in x] - for file in files: - file_pd = pd.read_fwf(os.path.join(args.senteval_probing_path, file), header=None) - files_train = file_pd[file_pd[0] == "tr"] - task_name = file.split(".")[0] - if not os.path.exists(os.path.join(args.senteval_probing_path, task_name)): - os.mkdir(os.path.join(args.senteval_probing_path, task_name)) - files_train.to_csv(os.path.join(args.senteval_probing_path, task_name, "train.csv")) - files_val = file_pd[file_pd[0] == "va"] - task_name = file.split(".")[0] - files_val.to_csv(os.path.join(args.senteval_probing_path, task_name, "val.csv")) - - files_test = file_pd[file_pd[0] == "te"] - task_name = file.split(".")[0] - files_test.to_csv(os.path.join(args.senteval_probing_path, task_name, "test.csv")) - - -parser = argparse.ArgumentParser() -parser.add_argument("--senteval_probing_path", type=str, help="path to original Senteval files") - -args = parser.parse_args() -parse_senteval_probing(args) diff --git a/scripts/sop/README.md b/scripts/sop/README.md deleted file mode 100644 index 482736e27..000000000 --- a/scripts/sop/README.md +++ /dev/null @@ -1,33 +0,0 @@ -# Downloading Wikipedia Corpus - -We use the preprocessing code from https://github.com/NVIDIA/DeepLearningExamples/tree/master/PyTorch/LanguageModeling/BERT#getting-the-data -and the bash scripts provided here is used to help with streamlining the data generation in the NVIDIA repository. - -First, git clone https://github.com/NVIDIA/DeepLearningExamples.git. -Then, move scripts/sop/create_wiki_sop_data.sh and scripts/sop/get_small_english_wiki.sh into DeepLearningExamples/PyTorch/LanguageModeling/BERT/data. - -Then, follow the instructions below: - -NVIDIA script download the latest Wikipedia dump. We use the Wikipedia dump 2020-03-01. -To download the Wikipedia dump 2020-03-01, replace line 29 of `DeepLearningExamples/PyTorch/LanguageModeling/BERT/data/WikiDownloader.py`: -`'en' : 'https://dumps.wikimedia.org/enwiki/latest/enwiki-latest-pages-articles.xml.bz2',` with `'en' : `https://dumps.wikimedia.org/enwiki/20200301/enwiki-20200301-pages-articles.xml.bz2`. - -The data creation for SOP is almost the same as MLM, except you need to edit the following. -In `DeepLearningExamples/PyTorch/LanguageModeling/BERT/data/TextSharding.py`, replace line 55: -`self.articles[global_article_count] = line.rstrip()` with `self.articles[global_article_count] = line.rstrip() + "\n ========THIS IS THE END OF ARTICLE.========"`. -This is because SOP requires a signal for the end of each Wikipedia article. - -Additionally, replace '/workspace/wikiextractor/WikiExtractor.py' in line 80 of -`DeepLearningExamples/PyTorch/LanguageModeling/BERT/data/bertPrep.py` with 'wikiextractor/WikiExtractor.py'. - -Run `bash create_wiki_sop_data.sh $lang $save_directory` -The NVIDIA code supports English (en) and Chinese (zh) wikipedia. - -For example, to download and process English Wikipedia and save it in `~/Download` directory, run -`bash create_wiki_sop_data.sh en ~/Download` - -The above command will download the entire English Wikipedia. - -In our experiments, we only use a small subset (around 5% of) the entire English Wikipedia, which has the same number of sentences as Wikitext103. -To get this subset, run `bash get_small_english_wiki.sh $path_to_wikicorpus_en`. where $path_to_wikicorpus_en is the directory where you saved the full processed `wikicorpus_en` corpus. - diff --git a/scripts/sop/create_wiki_sop_data.sh b/scripts/sop/create_wiki_sop_data.sh deleted file mode 100755 index 0f0722e24..000000000 --- a/scripts/sop/create_wiki_sop_data.sh +++ /dev/null @@ -1,49 +0,0 @@ -#!/bin/bash - -# Copyright (c) 2019 NVIDIA CORPORATION. All rights reserved. -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -lang=$1 #the language, 'en' for English wikipedia -export BERT_PREP_WORKING_DIR=$2 - -# clone wikiextractor if it doesn't exist -if [ ! -d "wikiextractor" ]; then - git clone https://github.com/attardi/wikiextractor.git -fi - -echo "Downloading $lang wikpedia in directory $save_dir" -# Download -python3 bertPrep.py --action download --dataset wikicorpus_$lang - - -# Properly format the text files -python3 bertPrep.py --action text_formatting --dataset wikicorpus_$lang - - -# Shard the text files (group wiki+books then shard) -python3 bertPrep.py --action sharding --dataset wikicorpus_$lang - - -# Combine sharded files into one -save_dir=$BERT_PREP_WORKING_DIR/sharded_training_shards_256_test_shards_256_fraction_0.2/wikicorpus_$lang -cat $save_dir/*training*.txt > $save_dir/train_$lang.txt -cat $save_dir/*test*.txt > $save_dir/test_$lang.txt -rm -rf $save_dir/wiki*training*.txt -rm -rf $save_dir/wiki*test*.txt - -# remove some remaining xml tags -sed -i 's/<[^>]*>//g' $save_dir/train_$lang.txt -sed -i 's/<[^>]*>//g' $save_dir/test_$lang.txt - -echo "Your corpus is saved in $save_dir" - diff --git a/scripts/sop/get_small_english_wiki.sh b/scripts/sop/get_small_english_wiki.sh deleted file mode 100644 index e61311543..000000000 --- a/scripts/sop/get_small_english_wiki.sh +++ /dev/null @@ -1,6 +0,0 @@ -wiki_path=$1 - -mkdir -p $wiki_path/wikipedia_sop_small -head -3978309 $wiki_path/train_en.txt > $wiki_path/wikipedia_sop_small/train.txt -head -10001 $wiki_path/test_en.txt > $wiki_path/wikipedia_sop_small/test.txt -tail -8438 $wiki_path/train_en.txt > $wiki_path/wikipedia_sop_small/valid.txt diff --git a/scripts/superglue-baselines.sh b/scripts/superglue-baselines.sh deleted file mode 100755 index f376af4d4..000000000 --- a/scripts/superglue-baselines.sh +++ /dev/null @@ -1,137 +0,0 @@ -#!/bin/bash -# Functions to run SuperGLUE BERT baselines. -# Usage: ./scripts/superglue-baselines.sh ${TASK} ${GPU_ID} ${SEED} -# - TASK: one of {"boolq", "commit", "copa", "multirc", "record", "rte", "wic", "wsc"}, -# as well as their *-bow variants and *++ for {"boolq", "commit", "copa", "rte"} -# - GPU_ID: GPU to use, or -1 for CPU. Defaults to 0. -# - SEED: random seed. Defaults to 111. - -source user_config.sh -seed=${3:-111} -gpuid=${2:-0} - -function boolq() { - python main.py --config jiant/config/superglue_bert.conf --overrides "random_seed = ${seed}, cuda = ${gpuid}, run_name = boolq, pretrain_tasks = \"boolq\", target_tasks = \"boolq\", do_pretrain = 1, do_target_task_training = 0, do_full_eval = 1, batch_size = 4, val_interval = 1000" -} - -function commit() { - python main.py --config jiant/config/superglue_bert.conf --overrides "random_seed = ${seed}, cuda = ${gpuid}, run_name = commitbank, pretrain_tasks = \"commitbank\", target_tasks = \"commitbank\", do_pretrain = 1, do_target_task_training = 0, do_full_eval = 1, batch_size = 4, val_interval = 60" -} - -function copa() { - python main.py --config jiant/config/superglue_bert.conf --overrides "random_seed = ${seed}, cuda = ${gpuid}, run_name = copa, pretrain_tasks = \"copa\", target_tasks = \"copa\", do_pretrain = 1, do_target_task_training = 0, do_full_eval = 1, batch_size = 4, val_interval = 100" -} - -function multirc() { - python main.py --config jiant/config/superglue_bert.conf --overrides "random_seed = ${seed}, cuda = ${gpuid}, run_name = multirc, pretrain_tasks = \"multirc\", target_tasks = \"multirc\", do_pretrain = 1, do_target_task_training = 0, do_full_eval = 1, batch_size = 4, val_interval = 1000, val_data_limit = -1" -} - -function record() { - python main.py --config jiant/config/superglue_bert.conf --overrides "random_seed = ${seed}, cuda = ${gpuid}, run_name = record, pretrain_tasks = \"record\", target_tasks = \"record\", do_pretrain = 1, do_target_task_training = 0, do_full_eval = 1, batch_size = 8, val_interval = 10000, val_data_limit = -1" -} - -function rte() { - python main.py --config jiant/config/superglue_bert.conf --overrides "random_seed = ${seed}, cuda = ${gpuid}, run_name = rte, pretrain_tasks = \"rte-superglue\", target_tasks = \"rte-superglue,broadcoverage-diagnostic,winogender-diagnostic\", do_pretrain = 1, do_target_task_training = 0, do_full_eval = 1, batch_size = 4, val_interval = 625" -} - -function wic() { - python main.py --config jiant/config/superglue_bert.conf --overrides "random_seed = ${seed}, cuda = ${gpuid}, run_name = wic, pretrain_tasks = \"wic\", target_tasks = \"wic\", do_pretrain = 1, do_target_task_training = 0, do_full_eval = 1, batch_size = 4, val_interval = 1000" -} - -function wsc() { - # NOTE: We use Adam b/c we were getting weird degenerate runs with BERT Adam - python main.py --config jiant/config/superglue_bert.conf --overrides "random_seed = ${seed}, cuda = ${gpuid}, run_name = wsc, pretrain_tasks = \"winograd-coreference\", target_tasks = \"winograd-coreference\", do_pretrain = 1, do_target_task_training = 0, do_full_eval = 1, batch_size = 4, val_interval = 139, optimizer = adam" -} - -function boolq_plus() { - python main.py --config jiant/config/superglue_bert.conf --overrides "random_seed = ${seed}, cuda = ${gpuid}, run_name = boolq_plus, pretrain_tasks = \"mnli\", target_tasks = \"boolq\", do_pretrain = 1, do_target_task_training = 1, do_full_eval = 1, batch_size = 4, val_interval = 1000, target_train_val_interval = 1000" -} - -function commit_plus() { - python main.py --config jiant/config/superglue_bert.conf --overrides "random_seed = ${seed}, cuda = ${gpuid}, run_name = commitbank_plus, pretrain_tasks = \"mnli\", target_tasks = \"commitbank\", do_pretrain = 1, do_target_task_training = 1, do_full_eval = 1, batch_size = 4, val_interval = 1000, target_train_val_interval = 60" -} - -function copa_plus() { - python main.py --config jiant/config/superglue_bert.conf --overrides "random_seed = ${seed}, cuda = ${gpuid}, run_name = copa_plus, pretrain_tasks = \"swag\", target_tasks = \"copa\", do_pretrain = 1, do_target_task_training = 1, do_full_eval = 1, batch_size = 4, val_interval = 1000, target_train_val_interval = 100" -} - -function rte_plus() { - python main.py --config jiant/config/superglue_bert.conf --overrides "random_seed = ${seed}, cuda = ${gpuid}, run_name = rte_plus, pretrain_tasks = \"mnli\", target_tasks = \"rte-superglue,winogender-diagnostic,broadcoverage-diagnostic\", do_pretrain = 1, do_target_task_training = 1, do_full_eval = 1, batch_size = 4, val_interval = 1000, target_train_val_interval = 625" -} - -function boolq_bow() { - python main.py --config jiant/config/superglue_bow.conf --overrides "random_seed = ${seed}, cuda = ${gpuid}, exp_name = \"bow-boolq\", run_name = boolq, pretrain_tasks = \"boolq\", target_tasks = \"boolq\", do_pretrain = 1, do_target_task_training = 0, do_full_eval = 1, val_interval = 1000" -} - -function commit_bow() { - python main.py --config jiant/config/superglue_bow.conf --overrides "random_seed = ${seed}, cuda = ${gpuid}, exp_name = \"bow-commit\", run_name = commitbank, pretrain_tasks = \"commitbank\", target_tasks = \"commitbank\", do_pretrain = 1, do_target_task_training = 0, do_full_eval = 1, val_interval = 60" -} - -function copa_bow() { - python main.py --config jiant/config/superglue_bow.conf --overrides "random_seed = ${seed}, cuda = ${gpuid}, exp_name = \"bow-copa\", run_name = copa, pretrain_tasks = \"copa\", target_tasks = \"copa\", do_pretrain = 1, do_target_task_training = 0, do_full_eval = 1, val_interval = 100" -} - -function multirc_bow() { - python main.py --config jiant/config/superglue_bow.conf --overrides "random_seed = ${seed}, cuda = ${gpuid}, exp_name = \"bow-multirc\", run_name = multirc, pretrain_tasks = \"multirc\", target_tasks = \"multirc\", do_pretrain = 1, do_target_task_training = 0, do_full_eval = 1, val_interval = 1000, val_data_limit = -1" -} - -function record_bow() { - python main.py --config jiant/config/superglue_bow.conf --overrides "random_seed = ${seed}, cuda = ${gpuid}, exp_name = \"bow-record\", run_name = record, pretrain_tasks = \"record\", target_tasks = \"record\", do_pretrain = 1, do_target_task_training = 0, do_full_eval = 1, batch_size = 8, val_interval = 10000, val_data_limit = -1" -} - -function rte_bow() { - python main.py --config jiant/config/superglue_bow.conf --overrides "random_seed = ${seed}, cuda = ${gpuid}, exp_name = \"bow-rte\", run_name = rte, pretrain_tasks = \"rte-superglue\", target_tasks = \"rte-superglue,broadcoverage-diagnostic,winogender-diagnostic\", do_pretrain = 1, do_target_task_training = 0, do_full_eval = 1, val_interval = 625" -} - -function wic_bow() { - python main.py --config jiant/config/superglue_bow.conf --overrides "random_seed = ${seed}, cuda = ${gpuid}, exp_name = \"bow-wic\", run_name = wic, pretrain_tasks = \"wic\", target_tasks = \"wic\", do_pretrain = 1, do_target_task_training = 0, do_full_eval = 1, val_interval = 1000" -} - -function wsc_bow() { - # NOTE: We use Adam b/c we were getting weird degenerate runs with BERT Adam - python main.py --config jiant/config/superglue_bow.conf --overrides "random_seed = ${seed}, cuda = ${gpuid}, exp_name = \"bow-wsc\", run_name = wsc, pretrain_tasks = \"winograd-coreference\", target_tasks = \"winograd-coreference\", do_pretrain = 1, do_target_task_training = 0, do_full_eval = 1, val_interval = 139, optimizer = adam" -} - -if [ $1 == "boolq" ]; then - boolq -elif [ $1 == "commit" ]; then - commit -elif [ $1 == "copa" ]; then - copa -elif [ $1 == "multirc" ]; then - multirc -elif [ $1 == "record" ]; then - record -elif [ $1 == "rte" ]; then - rte -elif [ $1 == "wic" ]; then - wic -elif [ $1 == "wsc" ]; then - wsc - -elif [ $1 == "boolq++" ]; then - boolq_plus -elif [ $1 == "commit++" ]; then - commit_plus -elif [ $1 == "copa++" ]; then - copa_plus -elif [ $1 == "rte++" ]; then - rte_plus - -elif [ $1 == "boolq-bow" ]; then - boolq_bow -elif [ $1 == "commit-bow" ]; then - commit_bow -elif [ $1 == "copa-bow" ]; then - copa_bow -elif [ $1 == "multirc-bow" ]; then - multirc_bow -elif [ $1 == "record-bow" ]; then - record_bow -elif [ $1 == "rte-bow" ]; then - rte_bow -elif [ $1 == "wic-bow" ]; then - wic_bow -elif [ $1 == "wsc-bow" ]; then - wsc_bow -fi diff --git a/scripts/update_config.py b/scripts/update_config.py deleted file mode 100644 index 3039882d3..000000000 --- a/scripts/update_config.py +++ /dev/null @@ -1,31 +0,0 @@ -""" -Overwrite a config file by renaming args. -Require one argument: path_to_file. -""" - -import sys - -from jiant.utils import config # use symlink from scripts to jiant - -# Mapping - key: old name, value: new name -name_dict = { - "task_patience": "lr_patience", - "do_train": "do_pretrain", - "train_for_eval": "do_target_task_training", - "do_eval": "do_full_eval", - "train_tasks": "pretrain_tasks", - "eval_tasks": "target_tasks", - "eval_data_fraction": "target_train_data_fraction", - "eval_val_interval": "target_train_val_interval", - "eval_max_vals": "target_train_max_vals", - "load_eval_checkpoint": "load_target_train_checkpoint", - "eval_data_fraction": "target_train_data_fraction", -} - -path = sys.argv[1] -params = config.params_from_file(path) -for old_name, new_name in name_dict.items(): - if old_name in params: - params[new_name] = params[old_name] - del params[old_name] -config.write_params(params, path) diff --git a/scripts/winograd/preprocess_winograd.py b/scripts/winograd/preprocess_winograd.py deleted file mode 100644 index 215473fb9..000000000 --- a/scripts/winograd/preprocess_winograd.py +++ /dev/null @@ -1,145 +0,0 @@ -#!/usr/bin/env python - -""" -This file will preprocess the SuperGLUE Winograd Schema Challenge data, aligning the span indices -to the tokenizaer of choice, and saving as a JSON file. - -An example of the span index transformation is below: -[Mr., Porter, is, nice] with span indices [0, 2] -> [Mr, ., Por, ter, is, nice ] -with span indices [0, 3]. - -Usage: - Run the below command from the root directory - python -m scripts.winograd.preprocess_winograd - -t {tokenizer_name} --data_dir {path/to/directory} - -The input file should be in jsonl form, with text and tags columns. The output will be -in JSON form. See realign_spans for more details. - -""" - -from typing import Tuple, List, Text -from jiant.utils import tokenizers -from jiant.utils import retokenize -from jiant.utils import utils -import argparse -import functools -import json -import os -import re -import sys -import multiprocessing -from tqdm import tqdm -import pandas as pd -import logging as log - -log.basicConfig(format="%(asctime)s: %(message)s", datefmt="%m/%d %I:%M:%S %p", level=log.INFO) - - -def realign_spans(record, tokenizer_name): - """ - Builds the indices alignment while also tokenizing the input - piece by piece. - - Parameters - ----------------------- - record: dict with the below fields - text: str - targets: list of dictionaries - label: bool - span1_index: int, start index of first span - span1_text: str, text of first span - span2_index: int, start index of second span - span2_text: str, text of second span - tokenizer_name: str - - Returns - ------------------------ - record: dict with the below fields: - text: str in tokenized form - targets: dictionary with the below fields - -label: bool - -span_1: (int, int) of token indices - -span1_text: str, the string - -span2: (int, int) of token indices - -span2_text: str, the string - """ - - # find span indices and text - text = record["text"].split() - span1 = record["targets"][0]["span1_index"] - span1_text = record["targets"][0]["span1_text"] - span2 = record["targets"][0]["span2_index"] - span2_text = record["targets"][0]["span2_text"] - - # construct end spans given span text space-tokenized length - span1 = [span1, span1 + len(span1_text.strip().split())] - span2 = [span2, span2 + len(span2_text.strip().split())] - indices = [span1, span2] - - sorted_indices = sorted(indices, key=lambda x: x[0]) - current_tokenization = [] - span_mapping = {} - - # align first span to tokenized text - aligner_fn = retokenize.get_aligner_fn(tokenizer_name) - _, new_tokens = aligner_fn(" ".join(text[: sorted_indices[0][0]])) - current_tokenization.extend(new_tokens) - new_span1start = len(current_tokenization) - _, span_tokens = aligner_fn(" ".join(text[sorted_indices[0][0] : sorted_indices[0][1]])) - current_tokenization.extend(span_tokens) - new_span1end = len(current_tokenization) - span_mapping[sorted_indices[0][0]] = [new_span1start, new_span1end] - - # re-indexing second span - _, new_tokens = aligner_fn(" ".join(text[sorted_indices[0][1] : sorted_indices[1][0]])) - current_tokenization.extend(new_tokens) - new_span2start = len(current_tokenization) - _, span_tokens = aligner_fn(" ".join(text[sorted_indices[1][0] : sorted_indices[1][1]])) - current_tokenization.extend(span_tokens) - new_span2end = len(current_tokenization) - span_mapping[sorted_indices[1][0]] = [new_span2start, new_span2end] - - # save back into record - _, all_text = aligner_fn(" ".join(text)) - record["targets"][0]["span1"] = span_mapping[record["targets"][0]["span1_index"]] - record["targets"][0]["span2"] = span_mapping[record["targets"][0]["span2_index"]] - record["text"] = " ".join(all_text) - return record - - -def _map_fn(record, tokenizer_name): - new_record = realign_spans(record, tokenizer_name) - return json.dumps(new_record) - - -def preprocess_winograd(fname, tokenizer_name, worker_pool): - if tokenizer_name.startswith("nyu-mll/"): - new_name = fname + ".retokenized." + tokenizer_name.replace("/", ".") - else: - new_name = fname + ".retokenized." + tokenizer_name - log.info("Processing file: %s", fname) - # decompress into list of dictionaries - inputs = list(pd.read_json(fname, lines=True).T.to_dict().values()) - log.info(" saving to %s", new_name) - map_fn = functools.partial(_map_fn, tokenizer_name=tokenizer_name) - with open(new_name, "w") as fd: - for line in tqdm(worker_pool.imap(map_fn, inputs, chunksize=500), total=len(inputs)): - fd.write(line) - fd.write("\n") - - -def main(args): - parser = argparse.ArgumentParser() - parser.add_argument("-t", dest="tokenizer_name", type=str, help="Tokenizer name.") - parser.add_argument("--data_dir", type=str, help="Path to data directory.") - args = parser.parse_args(args) - worker_pool = multiprocessing.Pool(2) - for fname in ["train.jsonl", "val.jsonl", "test_with_labels.jsonl"]: - fname = args.data_dir + fname - preprocess_winograd(fname, args.tokenizer_name, worker_pool=worker_pool) - - -if __name__ == "__main__": - main(sys.argv[1:]) - sys.exit(0) diff --git a/setup.py b/setup.py index 0711aca1c..8a5949dcc 100644 --- a/setup.py +++ b/setup.py @@ -1,83 +1,91 @@ -"""Setuptools package definition for PyPI/pip distribution - -Dependencies will need to be updated in the "install_requires" of setup() -below. Those dependencies are used to create the CircleCI virtual environment. -These are generally the same dependencies as in environment.yml, but should be -limited to dependencies required by most users. New directories added under -the jiant directory will also need to be added to the "packages" section of -setup(). - -Distributions are automatically versioned based on git tags. After creating a -new git tag, a release can be created by running: - - # install twine, if necessary - # pip install --user twine - - # create distribution - python setup.py sdist bdist_wheel - - # upload to PyPI - python -m twine upload dist/* - -Twine will prompt for login. Login details can be stored for reuse in the file -"~/.pypirc". See https://docs.python.org/3.3/distutils/packageindex.html#pypirc +""" +Simple check list from huggingface/transformers repo: https://github.com/huggingface/transformers/blob/master/setup.py +To create the package for pypi. +1. Change the version in __init__.py, setup.py and docs (if applicable). +2. Unpin specific versions from setup.py. +2. Commit these changes with the message: "Release: VERSION" +3. Add a tag in git to mark the release: "git tag VERSION -m'Adds tag VERSION for pypi' " + Push the tag to git: git push --tags origin master +4. Build both the sources and the wheel. Do not change anything in setup.py between + creating the wheel and the source distribution (obviously). + For the wheel, run: "python setup.py bdist_wheel" in the top level directory. + (this will build a wheel for the python version you use to build it). + For the sources, run: "python setup.py sdist" + You should now have a /dist directory with both .whl and .tar.gz source versions. +5. Check that everything looks correct by uploading the package to the pypi test server: + python3 -m twine upload --repository testpypi dist/* + Alternatively: + twine upload dist/* -r pypitest + (pypi suggest using twine as other methods upload files via plaintext.) + You may have to specify the repository url, use the following command then: + twine upload dist/* -r pypitest --repository-url=https://test.pypi.org/legacy/ + Check that you can install it in a virtualenv by running: + pip install -i https://testpypi.python.org/pypi jiant +6. Upload the final version to actual pypi: + twine upload dist/* -r pypi +7. Copy the release notes from RELEASE.md to the tag in github once everything is looking hunky-dory. +8. Add the release version to docs deployment (if applicable) +9. Update README.md to redirect to correct documentation. +""" -If you need to test a distribution before tagging, you can use the following -(with example version 0.1.0rc1), but take care to delete the distribution from -dist before the next twine upload to PyPI: +import shutil +from pathlib import Path - SETUPTOOLS_SCM_PRETEND_VERSION=0.1.0rc1 python setup.py sdist bdist_wheel - python -m twine upload --repository-url https://test.pypi.org/legacy/ dist/* -""" -import setuptools +from setuptools import find_packages, setup -with open("README.md", "r") as fh: - long_description = fh.read() +extras = {} +extras["testing"] = ["pytest", "pytest-cov", "pre-commit"] +extras["docs"] = ["sphinx"] +extras["quality"] = ["black == 19.10b0", "flake8-docstrings == 1.5.0", "flake8 >= 3.7.9", "mypy == 0.770"] +extras["dev"] = extras["testing"] + extras["quality"] -setuptools.setup( - name="jiant", +setup( + name="jiant2", + version="2.0.0", author="NYU Machine Learning for Language Group", author_email="bowman@nyu.edu", - description="jiant is a software toolkit for natural language processing research, designed to \ - facilitate work on multitask learning and transfer learning for sentence understanding tasks.", - long_description=long_description, + description="State-of-the-art Natural Language Processing toolkit for multi-task and transfer learning built on PyTorch.", + long_description=open("README.md", "r", encoding="utf-8").read(), long_description_content_type="text/markdown", - url="https://github.com/nyu-mll/jiant", + keywords="NLP deep learning transformer pytorch tensorflow BERT GPT GPT-2 google nyu datasets", license="MIT", - packages=[ - "jiant", - "jiant.allennlp_mods", - "jiant.metrics", - "jiant.modules", - "jiant.modules.onlstm", - "jiant.modules.prpn", - "jiant.huggingface_transformers_interface", - "jiant.tasks", - "jiant.utils", - ], + url="https://github.com/nyu-mll/jiant", + package_dir={"": "jiant"}, + packages=find_packages(), install_requires=[ - "torch==1.0.*", - "numpy==1.14.5", - "pandas==0.23.0", - "scikit-learn<0.23", # pinned for compatability w/ allennlp==0.8.4, see jiant issue 1088. - "allennlp==0.8.4", - "jsondiff", - "nltk==3.4.5", - "pyhocon==0.3.35", - "python-Levenshtein==0.12.0", - "sacremoses", - "transformers==2.6.0", - "tokenizers==0.5.2", - "ftfy", - "spacy", + "attrs == 19.3.0", + "bs4 == 0.0.1", + "jsonnet == 0.15.0", + "lxml == 4.5.1", + "nlp == 0.4.0", + "nltk >= 3.5", + "numexpr == 2.7.1", + "numpy == 1.18.4", + "pandas == 1.0.3", + "python-Levenshtein == 0.12.0", + "sacremoses == 0.0.43", + "seqeval == 0.0.12", + "scikit-learn == 0.22.2.post1", + "scipy == 1.4.1", + "sentencepiece == 0.1.86", + "tokenizers == 0.8.1.rc2", + "torch == 1.5.0", + "tqdm == 4.46.0", + "transformers == 3.0.2", + "torchvision == 0.6.0", ], - use_scm_version=True, - setup_requires=["setuptools_scm"], + extras_require=extras, + python_requires=">=3.6.0", classifiers=[ - "Programming Language :: Python :: 3", - "License :: OSI Approved :: MIT License", + "Development Status :: 4 - Beta", + "Intended Audience :: Developers", + "Intended Audience :: Education", + "Intended Audience :: Science/Research", + 'License :: OSI Approved :: MIT License', "Operating System :: OS Independent", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Topic :: Scientific/Engineering :: Artificial Intelligence", ], - include_package_data=True, - package_data={"": ["jiant/config/**/*.conf"]}, -) +) \ No newline at end of file diff --git a/tests/README.md b/tests/README.md new file mode 100644 index 000000000..bd78f2986 --- /dev/null +++ b/tests/README.md @@ -0,0 +1,7 @@ +### Tests + +To run tests, run `pytest` from the project root directory. + +#### Notes: +* By default, [tests marked "slow" or "gpu" will be skipped](https://github.com/pyeres/jiant/pull/10#issue-414779551) by the [CI system](https://app.circleci.com/pipelines/github/pyeres/jiant). +* To run "slow" and "gpu" tests (required for some PRs), run tests with `pytest jiant --runslow --rungpu`. diff --git a/tests/proj/main/components/test_task_sampler.py b/tests/proj/main/components/test_task_sampler.py new file mode 100644 index 000000000..c644f9070 --- /dev/null +++ b/tests/proj/main/components/test_task_sampler.py @@ -0,0 +1,53 @@ +import numpy as np +import pytest + +import jiant.proj.main.components.task_sampler as task_sampler + + +def test_time_dependent_prob_multitask_sampler_const_p(): + sampler = task_sampler.TimeDependentProbMultiTaskSampler( + task_dict={"rte": None, "mnli": None, "squad_v1": None,}, + rng=0, + task_to_unnormalized_prob_funcs_dict={"rte": "1", "mnli": "1", "squad_v1": "1",}, + ) + gold_p = np.ones(3) / 3 + assert np.array_equal(sampler.get_task_p(0), gold_p) + assert np.array_equal(sampler.get_task_p(500), gold_p) + assert np.array_equal(sampler.get_task_p(999), gold_p) + + +def test_time_dependent_prob_multitask_sampler_variable_p(): + sampler = task_sampler.TimeDependentProbMultiTaskSampler( + task_dict={"rte": None, "mnli": None, "squad_v1": None,}, + rng=0, + task_to_unnormalized_prob_funcs_dict={ + "rte": "1", + "mnli": "1 - t/1000", + "squad_v1": "exp(t/1000)", + }, + ) + assert np.array_equal(sampler.get_task_p(0), np.ones(3) / 3) + assert np.allclose(sampler.get_task_p(500), np.array([0.31758924, 0.15879462, 0.52361614])) + assert np.allclose( + sampler.get_task_p(999), np.array([2.69065663e-01, 2.69065663e-04, 7.30665271e-01]) + ) + + +def test_time_dependent_prob_multitask_sampler_handles_max_steps(): + sampler_1 = task_sampler.TimeDependentProbMultiTaskSampler( + task_dict={"rte": None}, rng=0, task_to_unnormalized_prob_funcs_dict={"rte": "1"}, + ) + sampler_2 = task_sampler.TimeDependentProbMultiTaskSampler( + task_dict={"rte": None}, + rng=0, + task_to_unnormalized_prob_funcs_dict={"rte": "1"}, + max_steps=10, + ) + for i in range(10): + sampler_1.pop() + sampler_2.pop() + sampler_1.pop() + with pytest.raises(IndexError): + sampler_2.pop() + sampler_2.reset_counter() + sampler_2.pop() diff --git a/tests/proj/simple/test_runscript.py b/tests/proj/simple/test_runscript.py new file mode 100644 index 000000000..6dc65ca04 --- /dev/null +++ b/tests/proj/simple/test_runscript.py @@ -0,0 +1,31 @@ +import os +import pytest + +import jiant.utils.python.io as py_io +from jiant.proj.simple import runscript as run +import jiant.scripts.download_data.runscript as downloader + + +@pytest.mark.parametrize("task_name", ["copa"]) +@pytest.mark.parametrize("model_type", ["bert-base-cased"]) +def test_simple_runscript(tmpdir, task_name, model_type): + RUN_NAME = f"{test_simple_runscript.__name__}_{task_name}_{model_type}" + data_dir = str(tmpdir.mkdir("data")) + exp_dir = str(tmpdir.mkdir("exp")) + + downloader.download_data([task_name], data_dir) + + args = run.RunConfiguration( + run_name=RUN_NAME, + exp_dir=exp_dir, + data_dir=data_dir, + model_type=model_type, + tasks=task_name, + train_examples_cap=16, + train_batch_size=16, + no_cuda=True, + ) + run.run_simple(args) + + val_metrics = py_io.read_json(os.path.join(exp_dir, "runs", RUN_NAME, "val_metrics.json")) + assert val_metrics["aggregated"] > 0 diff --git a/tests/tasks/lib/resources/data/mnli/mnli_test.jsonl b/tests/tasks/lib/resources/data/mnli/mnli_test.jsonl new file mode 100644 index 000000000..dd3c4cc87 --- /dev/null +++ b/tests/tasks/lib/resources/data/mnli/mnli_test.jsonl @@ -0,0 +1,5 @@ +{"premise": "Hierbas, ans seco, ans dulce, and frigola are just a few names worth keeping a look-out for.", "hypothesis": "Hierbas is a name worth looking out for."} +{"premise": "The extent of the behavioral effects would depend in part on the structure of the individual account program and any limits on accessing the funds.", "hypothesis": "Many people would be very unhappy to loose control over their own money."} +{"premise": "Timely access to information is in the best interests of both GAO and the agencies.", "hypothesis": "It is in everyone's best interest to have access to information in a timely manner."} +{"premise": "Based in the Auvergnat spa town of Vichy, the French government often proved more zealous than its masters in suppressing civil liberties and drawing up anti-Jewish legislation.", "hypothesis": "The French government passed anti-Jewish laws aimed at helping the Nazi."} +{"premise": "Built in 1870, its canopy of stained glass and cast iron is the oldest in Dublin; its enthusiastic interior decoration is also typical of the era.", "hypothesis": "It was constructed in 1870 and has the oldest canopy in Dublin."} \ No newline at end of file diff --git a/tests/tasks/lib/resources/data/mnli/mnli_train.jsonl b/tests/tasks/lib/resources/data/mnli/mnli_train.jsonl new file mode 100644 index 000000000..6942941b7 --- /dev/null +++ b/tests/tasks/lib/resources/data/mnli/mnli_train.jsonl @@ -0,0 +1,5 @@ +{"premise": "Conceptually cream skimming has two basic dimensions - product and geography.", "hypothesis": "Product and geography are what make cream skimming work. ", "label": "neutral"} +{"premise": "you know during the season and i guess at at your level uh you lose them to the next level if if they decide to recall the the parent team the Braves decide to call to recall a guy from triple A then a double A guy goes up to replace him and a single A guy goes up to replace him", "hypothesis": "You lose the things to the following level if the people recall.", "label": "entailment"} +{"premise": "One of our number will carry out your instructions minutely.", "hypothesis": "A member of my team will execute your orders with immense precision.", "label": "entailment"} +{"premise": "How do you know? All this is their information again.", "hypothesis": "This information belongs to them.", "label": "entailment"} +{"premise": "yeah i tell you what though if you go price some of those tennis shoes i can see why now you know they're getting up in the hundred dollar range", "hypothesis": "The tennis shoes have a range of prices.", "label": "neutral"} \ No newline at end of file diff --git a/tests/tasks/lib/resources/data/mnli/mnli_val.jsonl b/tests/tasks/lib/resources/data/mnli/mnli_val.jsonl new file mode 100644 index 000000000..c1ceece8d --- /dev/null +++ b/tests/tasks/lib/resources/data/mnli/mnli_val.jsonl @@ -0,0 +1,5 @@ +{"premise": "The new rights are nice enough", "hypothesis": "Everyone really likes the newest benefits ", "label": "neutral"} +{"premise": "This site includes a list of all award winners and a searchable database of Government Executive articles.", "hypothesis": "The Government Executive articles housed on the website are not able to be searched.", "label": "contradiction"} +{"premise": "uh i don't know i i have mixed emotions about him uh sometimes i like him but at the same times i love to see somebody beat him", "hypothesis": "I like him for the most part, but would still enjoy seeing someone beat him.", "label": "entailment"} +{"premise": "yeah i i think my favorite restaurant is always been the one closest you know the closest as long as it's it meets the minimum criteria you know of good food", "hypothesis": "My favorite restaurants are always at least a hundred miles away from my house. ", "label": "contradiction"} +{"premise": "i don't know um do you do a lot of camping", "hypothesis": "I know exactly.", "label": "contradiction"} \ No newline at end of file diff --git a/tests/tasks/lib/resources/data/spr1/test.jsonl b/tests/tasks/lib/resources/data/spr1/test.jsonl new file mode 100644 index 000000000..9a258c530 --- /dev/null +++ b/tests/tasks/lib/resources/data/spr1/test.jsonl @@ -0,0 +1,2 @@ +{"text": "The acquisition strengthens BSN 's position in the European pasta market .", "info": {"split": "test", "sent_id": "2254_8"}, "targets": [{"span1": [2, 3], "span2": [1, 2], "label": ["existed_after", "existed_during", "instigation", "manipulated_by_another"]}, {"span1": [2, 3], "span2": [5, 6], "label": ["change_of_state", "existed_after", "existed_before", "existed_during", "location_of_event", "manipulated_by_another", "predicate_changed_argument"]}]} +{"text": "In fact , some of the association 's members -- long-term , buy-and-hold investors -- welcomed the drop in prices .", "info": {"split": "test", "sent_id": "2386_13"}, "targets": [{"span1": [15, 16], "span2": [17, 18], "label": ["existed_during", "manipulated_by_another"]}, {"span1": [15, 16], "span2": [3, 4], "label": ["awareness", "existed_after", "existed_before", "existed_during", "instigation", "volition"]}]} diff --git a/tests/tasks/lib/resources/data/spr1/train.jsonl b/tests/tasks/lib/resources/data/spr1/train.jsonl new file mode 100644 index 000000000..cb83e6032 --- /dev/null +++ b/tests/tasks/lib/resources/data/spr1/train.jsonl @@ -0,0 +1,2 @@ +{"text": "This conjures up images of a nation full of trim , muscular folks , and suggests couch potatoes are out of season .", "info": {"split": "train", "sent_id": "0409_35"}, "targets": [{"span1": [1, 2], "span2": [0, 1], "label": []}, {"span1": [15, 16], "span2": [0, 1], "label": ["existed_during", "instigation", "manipulated_by_another"]}]} +{"text": "`` I spent so much money that if I look at it , and I 'm not on it , I feel guilty . ''", "info": {"split": "train", "sent_id": "0409_32"}, "targets": [{"span1": [2, 3], "span2": [1, 2], "label": ["awareness", "change_of_state", "existed_after", "existed_before", "existed_during", "exists_as_physical", "instigation", "makes_physical_contact", "predicate_changed_argument", "sentient", "volition"]}, {"span1": [2, 3], "span2": [5, 6], "label": ["changes_possession", "existed_after", "existed_before", "existed_during", "manipulated_by_another"]}]} diff --git a/tests/tasks/lib/resources/data/sst/test.jsonl b/tests/tasks/lib/resources/data/sst/test.jsonl new file mode 100644 index 000000000..a5ee0489e --- /dev/null +++ b/tests/tasks/lib/resources/data/sst/test.jsonl @@ -0,0 +1,5 @@ +{"text": "uneasy mishmash of styles and genres ."} +{"text": "this film 's relationship to actual tension is the same as what christmas-tree flocking in a spray can is to actual snow : a poor -- if durable -- imitation ."} +{"text": "by the end of no such thing the audience , like beatrice , has a watchful affection for the monster ."} +{"text": "director rob marshall went out gunning to make a great one ."} +{"text": "lathan and diggs have considerable personal charm , and their screen rapport makes the old story seem new ."} diff --git a/tests/tasks/lib/resources/data/sst/train.jsonl b/tests/tasks/lib/resources/data/sst/train.jsonl new file mode 100644 index 000000000..fcbe7769c --- /dev/null +++ b/tests/tasks/lib/resources/data/sst/train.jsonl @@ -0,0 +1,5 @@ +{"text": "hide new secretions from the parental units ", "label": "0"} +{"text": "contains no wit , only labored gags ", "label": "0"} +{"text": "that loves its characters and communicates something rather beautiful about human nature ", "label": "1"} +{"text": "remains utterly satisfied to remain the same throughout ", "label": "0"} +{"text": "on the worst revenge-of-the-nerds clich\u00e9s the filmmakers could dredge up ", "label": "0"} diff --git a/tests/tasks/lib/resources/data/sst/val.jsonl b/tests/tasks/lib/resources/data/sst/val.jsonl new file mode 100644 index 000000000..1bc6efb6e --- /dev/null +++ b/tests/tasks/lib/resources/data/sst/val.jsonl @@ -0,0 +1,5 @@ +{"text": "it 's a charming and often affecting journey . ", "label": "1"} +{"text": "unflinchingly bleak and desperate ", "label": "0"} +{"text": "allows us to hope that nolan is poised to embark a major career as a commercial yet inventive filmmaker . ", "label": "1"} +{"text": "the acting , costumes , music , cinematography and sound are all astounding given the production 's austere locales . ", "label": "1"} +{"text": "it 's slow -- very , very slow . ", "label": "0"} diff --git a/tests/tasks/lib/resources/mnli.json b/tests/tasks/lib/resources/mnli.json new file mode 100644 index 000000000..01fa70a26 --- /dev/null +++ b/tests/tasks/lib/resources/mnli.json @@ -0,0 +1,9 @@ +{ + "task": "mnli", + "paths": { + "train": "data/mnli/mnli_train.jsonl", + "val": "data/mnli/mnli_val.jsonl", + "test": "data/mnli/mnli_test.jsonl" + }, + "name": "mnli" +} \ No newline at end of file diff --git a/tests/tasks/lib/resources/spr1.json b/tests/tasks/lib/resources/spr1.json new file mode 100644 index 000000000..5b17f2bed --- /dev/null +++ b/tests/tasks/lib/resources/spr1.json @@ -0,0 +1,8 @@ +{ + "task": "spr1", + "paths": { + "train": "data/spr1/train.jsonl", + "val": "data/spr1/test.jsonl" + }, + "name": "spr1" +} diff --git a/tests/tasks/lib/resources/sst.json b/tests/tasks/lib/resources/sst.json new file mode 100644 index 000000000..c53939993 --- /dev/null +++ b/tests/tasks/lib/resources/sst.json @@ -0,0 +1,9 @@ +{ + "task": "sst", + "paths": { + "train": "data/sst/train.jsonl", + "val": "data/sst/val.jsonl", + "test": "data/sst/test.jsonl" + }, + "name": "sst" +} diff --git a/tests/tasks/lib/test_mlm_premasked.py b/tests/tasks/lib/test_mlm_premasked.py new file mode 100644 index 000000000..2a823b8b8 --- /dev/null +++ b/tests/tasks/lib/test_mlm_premasked.py @@ -0,0 +1,31 @@ +import transformers + +import jiant.shared.model_resolution as model_resolution +import jiant.tasks as tasks + + +def test_tokenization_and_featurization(): + task = tasks.MLMPremaskedTask(name="mlm_premasked", path_dict={}) + tokenizer = transformers.RobertaTokenizer.from_pretrained("roberta-base") + example = task.Example( + guid=None, + text="Hi, my name is Bob Roberts.", + masked_spans=[[15, 18]], + ) + tokenized_example = example.tokenize(tokenizer=tokenizer) + assert tokenized_example.masked_tokens == \ + ['Hi', ',', 'Ġmy', 'Ġname', 'Ġis', 'Ġ', '', 'ĠRoberts', '.'] + assert tokenized_example.label_tokens == \ + ['', '', '', '', '', '', 'Bob', '', ''] + + data_row = tokenized_example.featurize( + tokenizer=tokenizer, + feat_spec=model_resolution.build_featurization_spec( + model_type="roberta-base", + max_seq_length=16, + ) + ) + assert list(data_row.masked_input_ids) == \ + [0, 30086, 6, 127, 766, 16, 1437, 50264, 6274, 4, 2, 1, 1, 1, 1, 1] + assert list(data_row.masked_lm_labels) == \ + [-100, -100, -100, -100, -100, -100, -100, 25158, -100, -100, -100, -100, -100, -100, -100, -100] diff --git a/tests/tasks/lib/test_mlm_pretokenized.py b/tests/tasks/lib/test_mlm_pretokenized.py new file mode 100644 index 000000000..559d50a9f --- /dev/null +++ b/tests/tasks/lib/test_mlm_pretokenized.py @@ -0,0 +1,31 @@ +import transformers + +import jiant.shared.model_resolution as model_resolution +import jiant.tasks as tasks + + +def test_tokenization_and_featurization(): + task = tasks.MLMPretokenizedTask(name="mlm_pretokenized", path_dict={}) + tokenizer = transformers.RobertaTokenizer.from_pretrained("roberta-base") + example = task.Example( + guid=None, + tokenized_text=['Hi', ',', 'Ġmy', 'Ġname', 'Ġis', 'ĠBob', 'ĠRoberts', '.'], + masked_spans=[[2, 3], [5, 6]], + ) + tokenized_example = example.tokenize(tokenizer=tokenizer) + assert tokenized_example.masked_tokens == \ + ['Hi', ',', 'Ġmy', 'Ġname', 'Ġis', 'ĠBob', 'ĠRoberts', '.'] + assert tokenized_example.label_tokens == \ + ['', '', 'Ġmy', '', '', 'ĠBob', '', ''] + + data_row = tokenized_example.featurize( + tokenizer=tokenizer, + feat_spec=model_resolution.build_featurization_spec( + model_type="roberta-base", + max_seq_length=16, + ) + ) + assert list(data_row.masked_input_ids) == \ + [0, 30086, 6, 127, 766, 16, 3045, 6274, 4, 2, 1, 1, 1, 1, 1, 1] + assert list(data_row.masked_lm_labels) == \ + [-100, -100, -100, 127, -100, -100, 3045, -100, -100, -100, -100, -100, -100, -100, -100, -100] diff --git a/tests/tasks/lib/test_mnli.py b/tests/tasks/lib/test_mnli.py new file mode 100644 index 000000000..2b564e41d --- /dev/null +++ b/tests/tasks/lib/test_mnli.py @@ -0,0 +1,321 @@ +import os +from collections import Counter +import numpy as np + +from jiant.shared import model_resolution +from jiant.tasks import create_task_from_config_path +from jiant.utils.testing.tokenizer import SimpleSpaceTokenizer + + +TRAIN_EXAMPLES = [ + { + "guid": "train-0", + "premise": "Conceptually cream skimming has two basic dimensions - product and geography.", + "hypothesis": "Product and geography are what make cream skimming work. ", + "label": "neutral", + }, + { + "guid": "train-1", + "premise": "you know during the season and i guess at at your level uh you lose them to the next level if if they decide to recall the the parent team the Braves decide to call to recall a guy from triple A then a double A guy goes up to replace him and a single A guy goes up to replace him", + "hypothesis": "You lose the things to the following level if the people recall.", + "label": "entailment", + }, + { + "guid": "train-2", + "premise": "One of our number will carry out your instructions minutely.", + "hypothesis": "A member of my team will execute your orders with immense precision.", + "label": "entailment", + }, + { + "guid": "train-3", + "premise": "How do you know? All this is their information again.", + "hypothesis": "This information belongs to them.", + "label": "entailment", + }, + { + "guid": "train-4", + "premise": "yeah i tell you what though if you go price some of those tennis shoes i can see why now you know they're getting up in the hundred dollar range", + "hypothesis": "The tennis shoes have a range of prices.", + "label": "neutral", + }, +] + +TOKENIZED_TRAIN_EXAMPLES = [ + { + "guid": "train-0", + "premise": [ + "Conceptually", + "cream", + "skimming", + "has", + "two", + "basic", + "dimensions", + "-", + "product", + "and", + "geography.", + ], + "hypothesis": [ + "Product", + "and", + "geography", + "are", + "what", + "make", + "cream", + "skimming", + "work.", + ], + "label_id": 2, + }, + { + "guid": "train-1", + "premise": [ + "you", + "know", + "during", + "the", + "season", + "and", + "i", + "guess", + "at", + "at", + "your", + "level", + "uh", + "you", + "lose", + "them", + "to", + "the", + "next", + "level", + "if", + "if", + "they", + "decide", + "to", + "recall", + "the", + "the", + "parent", + "team", + "the", + "Braves", + "decide", + "to", + "call", + "to", + "recall", + "a", + "guy", + "from", + "triple", + "A", + "then", + "a", + "double", + "A", + "guy", + "goes", + "up", + "to", + "replace", + "him", + "and", + "a", + "single", + "A", + "guy", + "goes", + "up", + "to", + "replace", + "him", + ], + "hypothesis": [ + "You", + "lose", + "the", + "things", + "to", + "the", + "following", + "level", + "if", + "the", + "people", + "recall.", + ], + "label_id": 1, + }, + { + "guid": "train-2", + "premise": [ + "One", + "of", + "our", + "number", + "will", + "carry", + "out", + "your", + "instructions", + "minutely.", + ], + "hypothesis": [ + "A", + "member", + "of", + "my", + "team", + "will", + "execute", + "your", + "orders", + "with", + "immense", + "precision.", + ], + "label_id": 1, + }, + { + "guid": "train-3", + "premise": [ + "How", + "do", + "you", + "know?", + "All", + "this", + "is", + "their", + "information", + "again.", + ], + "hypothesis": ["This", "information", "belongs", "to", "them."], + "label_id": 1, + }, + { + "guid": "train-4", + "premise": [ + "yeah", + "i", + "tell", + "you", + "what", + "though", + "if", + "you", + "go", + "price", + "some", + "of", + "those", + "tennis", + "shoes", + "i", + "can", + "see", + "why", + "now", + "you", + "know", + "they're", + "getting", + "up", + "in", + "the", + "hundred", + "dollar", + "range", + ], + "hypothesis": ["The", "tennis", "shoes", "have", "a", "range", "of", "prices."], + "label_id": 2, + }, +] + +FEATURIZED_TRAIN_EXAMPLE_0 = { + "guid": "train-0", + "input_ids": np.array([1, 4, 5, 6, 7, 8, 9, 10, 11, 2, 15, 13, 16, 17, 18, 19, 5, 6, 20, 2]), + "input_mask": np.array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]), + "segment_ids": np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]), + "label_id": 2, + "tokens": [ + "", + "Conceptually", + "cream", + "skimming", + "has", + "two", + "basic", + "dimensions", + "-", + "", + "Product", + "and", + "geography", + "are", + "what", + "make", + "cream", + "skimming", + "work.", + "", + ], +} + + +def test_featurization_of_task_data(): + # Test reading the task-specific toy dataset into examples. + task = create_task_from_config_path( + os.path.join(os.path.dirname(__file__), "resources/mnli.json"), verbose=False + ) + # Test getting train, val, and test examples. Only the contents of train are checked. + train_examples = task.get_train_examples() + val_examples = task.get_val_examples() + test_examples = task.get_test_examples() + for train_example_dataclass, raw_example_dict in zip(train_examples, TRAIN_EXAMPLES): + assert train_example_dataclass.to_dict() == raw_example_dict + assert val_examples + assert test_examples + + # Testing conversion of examples into tokenized examples + # the dummy tokenizer requires a vocab — using a Counter here to find that vocab from the data: + token_counter = Counter() + for example in train_examples: + token_counter.update(example.premise.split()) + token_counter.update(example.hypothesis.split()) + token_vocab = list(token_counter.keys()) + tokenizer = SimpleSpaceTokenizer(vocabulary=token_vocab) + tokenized_examples = [example.tokenize(tokenizer) for example in train_examples] + for tokenized_example, expected_tokenized_example in zip( + tokenized_examples, TOKENIZED_TRAIN_EXAMPLES + ): + assert tokenized_example.to_dict() == expected_tokenized_example + + # Testing conversion of a tokenized example to a featurized example + train_example_0_length = len(tokenized_examples[0].premise) + len( + tokenized_examples[0].hypothesis + ) + feat_spec = model_resolution.build_featurization_spec( + model_type="bert-", max_seq_length=train_example_0_length + ) + featurized_examples = [ + tokenized_example.featurize(tokenizer=tokenizer, feat_spec=feat_spec) + for tokenized_example in tokenized_examples + ] + featurized_example_0_dict = featurized_examples[0].to_dict() + # not bothering to compare the input_ids because they were made by a dummy tokenizer. + assert "input_ids" in featurized_example_0_dict + assert featurized_example_0_dict["guid"] == FEATURIZED_TRAIN_EXAMPLE_0["guid"] + assert ( + featurized_example_0_dict["input_mask"] == FEATURIZED_TRAIN_EXAMPLE_0["input_mask"] + ).all() + assert ( + featurized_example_0_dict["segment_ids"] == FEATURIZED_TRAIN_EXAMPLE_0["segment_ids"] + ).all() + assert featurized_example_0_dict["label_id"] == FEATURIZED_TRAIN_EXAMPLE_0["label_id"] + assert featurized_example_0_dict["tokens"] == FEATURIZED_TRAIN_EXAMPLE_0["tokens"] diff --git a/tests/tasks/lib/test_spr1.py b/tests/tasks/lib/test_spr1.py new file mode 100644 index 000000000..fb8aefb2a --- /dev/null +++ b/tests/tasks/lib/test_spr1.py @@ -0,0 +1,339 @@ +import os +from collections import Counter + +import numpy as np +import transformers +from unittest.mock import Mock + +from jiant.shared import model_resolution +from jiant.tasks import create_task_from_config_path +from jiant.utils.testing.tokenizer import SimpleSpaceTokenizer + + +TRAIN_EXAMPLES = [ + { + "guid": "train-0-0", + "text": "This conjures up images of a nation full of trim , muscular folks , and suggests " + "couch potatoes are out of season .", + "span1": [1, 2], + "span2": [0, 1], + "labels": [], + }, + { + "guid": "train-0-1", + "text": "This conjures up images of a nation full of trim , muscular folks , and suggests " + "couch potatoes are out of season .", + "span1": [15, 16], + "span2": [0, 1], + "labels": ["existed_during", "instigation", "manipulated_by_another"], + }, + { + "guid": "train-1-0", + "text": "`` I spent so much money that if I look at it , and I 'm not on it , I feel guilty" + " . ''", + "span1": [2, 3], + "span2": [1, 2], + "labels": [ + "awareness", + "change_of_state", + "existed_after", + "existed_before", + "existed_during", + "exists_as_physical", + "instigation", + "makes_physical_contact", + "predicate_changed_argument", + "sentient", + "volition", + ], + }, + { + "guid": "train-1-1", + "text": "`` I spent so much money that if I look at it , and I 'm not on it , I feel guilty" + " . ''", + "span1": [2, 3], + "span2": [5, 6], + "labels": [ + "changes_possession", + "existed_after", + "existed_before", + "existed_during", + "manipulated_by_another", + ], + }, +] + + +TOKENIZED_TRAIN_EXAMPLES = [ + { + "guid": "train-0-0", + "tokens": [ + "This", + "conjures", + "up", + "images", + "of", + "a", + "nation", + "full", + "of", + "trim", + ",", + "muscular", + "folks", + ",", + "and", + "suggests", + "couch", + "potatoes", + "are", + "out", + "of", + "season", + ".", + ], + "span1_span": (1, 2), + "span2_span": (0, 1), + "span1_text": "conjures", + "span2_text": "This", + "label_ids": [], + "label_num": 18, + }, + { + "guid": "train-0-1", + "tokens": [ + "This", + "conjures", + "up", + "images", + "of", + "a", + "nation", + "full", + "of", + "trim", + ",", + "muscular", + "folks", + ",", + "and", + "suggests", + "couch", + "potatoes", + "are", + "out", + "of", + "season", + ".", + ], + "span1_span": (15, 16), + "span2_span": (0, 1), + "span1_text": "suggests", + "span2_text": "This", + "label_ids": [8, 10, 13], + "label_num": 18, + }, + { + "guid": "train-1-0", + "tokens": [ + "``", + "I", + "spent", + "so", + "much", + "money", + "that", + "if", + "I", + "look", + "at", + "it", + ",", + "and", + "I", + "'m", + "not", + "on", + "it", + ",", + "I", + "feel", + "guilty", + ".", + "''", + ], + "span1_span": (2, 3), + "span2_span": (1, 2), + "span1_text": "spent", + "span2_text": "I", + "label_ids": [0, 2, 6, 7, 8, 9, 10, 12, 14, 15, 17], + "label_num": 18, + }, + { + "guid": "train-1-1", + "tokens": [ + "``", + "I", + "spent", + "so", + "much", + "money", + "that", + "if", + "I", + "look", + "at", + "it", + ",", + "and", + "I", + "'m", + "not", + "on", + "it", + ",", + "I", + "feel", + "guilty", + ".", + "''", + ], + "span1_span": (2, 3), + "span2_span": (5, 6), + "span1_text": "spent", + "span2_text": "money", + "label_ids": [3, 6, 7, 8, 13], + "label_num": 18, + }, +] + + +FEATURIZED_TRAIN_EXAMPLE_0 = { + "guid": "train-0-0", + "input_ids": np.array( + [ + 1, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 8, + 12, + 13, + 14, + 15, + 13, + 16, + 17, + 18, + 19, + 20, + 21, + 8, + 22, + 23, + 2, + 0, + 0, + ] + ), + "input_mask": np.array( + [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0] + ), + "segment_ids": np.array( + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + ), + "label_ids": np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), + "spans": np.array([[2, 2], [1, 1]]), + "span1_text": "conjures", + "span2_text": "This", + "tokens": [ + "", + "This", + "conjures", + "up", + "images", + "of", + "a", + "nation", + "full", + "of", + "trim", + ",", + "muscular", + "folks", + ",", + "and", + "suggests", + "couch", + "potatoes", + "are", + "out", + "of", + "season", + ".", + "", + ], +} + + +def test_featurization_of_task_data(): + # Test reading the task-specific toy dataset into examples. + task = create_task_from_config_path( + os.path.join(os.path.dirname(__file__), "resources/spr1.json"), verbose=True + ) + # Test getting train, val, and test examples. Only the contents of train are checked. + train_examples = task.get_train_examples() + val_examples = task.get_val_examples() + for train_example_dataclass, raw_example_dict in zip(train_examples, TRAIN_EXAMPLES): + assert train_example_dataclass.to_dict() == raw_example_dict + assert val_examples + + # Testing conversion of examples into tokenized examples + # the dummy tokenizer requires a vocab — using a Counter here to find that vocab from the data: + token_counter = Counter() + for example in train_examples: + token_counter.update(example.text.split()) + token_vocab = list(token_counter.keys()) + space_tokenizer = SimpleSpaceTokenizer(vocabulary=token_vocab) + + # Mocking to pass normalize_tokenizations's isinstance check during example.tokenize(tokenizer) + tokenizer = Mock(spec_set=transformers.RobertaTokenizer) + tokenizer.tokenize.side_effect = space_tokenizer.tokenize + tokenized_examples = [example.tokenize(tokenizer) for example in train_examples] + for tokenized_example, expected_tokenized_example in zip( + tokenized_examples, TOKENIZED_TRAIN_EXAMPLES + ): + assert tokenized_example.to_dict() == expected_tokenized_example + # Dropping the mock and continuing the test with the space tokenizer + tokenizer = space_tokenizer + + # Testing conversion of a tokenized example to a featurized example + train_example_0_length = len(tokenized_examples[0].tokens) + 4 + feat_spec = model_resolution.build_featurization_spec( + model_type="bert-", max_seq_length=train_example_0_length + ) + featurized_examples = [ + tokenized_example.featurize(tokenizer=tokenizer, feat_spec=feat_spec) + for tokenized_example in tokenized_examples + ] + featurized_example_0_dict = featurized_examples[0].to_dict() + + # not bothering to compare the input_ids because they were made by a dummy tokenizer. + assert "input_ids" in featurized_example_0_dict + assert featurized_example_0_dict["guid"] == FEATURIZED_TRAIN_EXAMPLE_0["guid"] + assert ( + featurized_example_0_dict["input_mask"] == FEATURIZED_TRAIN_EXAMPLE_0["input_mask"] + ).all() + assert ( + featurized_example_0_dict["segment_ids"] == FEATURIZED_TRAIN_EXAMPLE_0["segment_ids"] + ).all() + assert (featurized_example_0_dict["label_ids"] == FEATURIZED_TRAIN_EXAMPLE_0["label_ids"]).all() + assert featurized_example_0_dict["tokens"] == FEATURIZED_TRAIN_EXAMPLE_0["tokens"] + assert featurized_example_0_dict["span1_text"] == FEATURIZED_TRAIN_EXAMPLE_0["span1_text"] + assert featurized_example_0_dict["span2_text"] == FEATURIZED_TRAIN_EXAMPLE_0["span2_text"] + assert (featurized_example_0_dict["spans"] == FEATURIZED_TRAIN_EXAMPLE_0["spans"]).all() diff --git a/tests/tasks/lib/test_sst.py b/tests/tasks/lib/test_sst.py new file mode 100644 index 000000000..3a76f28f1 --- /dev/null +++ b/tests/tasks/lib/test_sst.py @@ -0,0 +1,132 @@ +import os +from collections import Counter + +import numpy as np + +from jiant.tasks import create_task_from_config_path +from jiant.utils.testing.tokenizer import SimpleSpaceTokenizer + + +TRAIN_EXAMPLES = [ + {"guid": "train-0", "text": "hide new secretions from the parental units ", "label": "0"}, + {"guid": "train-1", "text": "contains no wit , only labored gags ", "label": "0"}, + { + "guid": "train-2", + "text": "that loves its characters and communicates something rather beautiful about " + "human nature ", + "label": "1", + }, + { + "guid": "train-3", + "text": "remains utterly satisfied to remain the same throughout ", + "label": "0", + }, + { + "guid": "train-4", + "text": "on the worst revenge-of-the-nerds clich\u00e9s the filmmakers could dredge up ", + "label": "0", + }, +] + +TOKENIZED_TRAIN_EXAMPLES = [ + { + "guid": "train-0", + "text": ["hide", "new", "secretions", "from", "the", "parental", "units"], + "label_id": 0, + }, + { + "guid": "train-1", + "text": ["contains", "no", "wit", ",", "only", "labored", "gags"], + "label_id": 0, + }, + { + "guid": "train-2", + "text": [ + "that", + "loves", + "its", + "characters", + "and", + "communicates", + "something", + "rather", + "beautiful", + "about", + "human", + "nature", + ], + "label_id": 1, + }, + { + "guid": "train-3", + "text": ["remains", "utterly", "satisfied", "to", "remain", "the", "same", "throughout"], + "label_id": 0, + }, + { + "guid": "train-4", + "text": [ + "on", + "the", + "worst", + "revenge-of-the-nerds", + "clich\u00e9s", + "the", + "filmmakers", + "could", + "dredge", + "up", + ], + "label_id": 0, + }, +] + +FEATURIZED_TRAIN_EXAMPLE_0 = { + "guid": "train-0", + "input_ids": np.array([1, 4, 5, 6, 7, 8, 9, 10, 2, 0]), + "input_mask": np.array([1, 1, 1, 1, 1, 1, 1, 1, 1, 0]), + "segment_ids": np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), + "label_id": 0, + "tokens": ["", "hide", "new", "secretions", "from", "the", "parental", "units", ""], +} + + +def test_featurization_of_task_data(): + # Test reading the task-specific toy dataset into examples. + task = create_task_from_config_path( + os.path.join(os.path.dirname(__file__), "resources/sst.json"), verbose=True + ) + examples = task.get_train_examples() + for example_dataclass, raw_example_dict in zip(examples, TRAIN_EXAMPLES): + assert example_dataclass.to_dict() == raw_example_dict + + # Testing conversion of examples into tokenized examples + # the dummy tokenizer requires a vocab — using a Counter here to find that vocab from the data: + token_counter = Counter() + for example in examples: + token_counter.update(example.text.split()) + token_vocab = list(token_counter.keys()) + tokenizer = SimpleSpaceTokenizer(vocabulary=token_vocab) + tokenized_examples = [example.tokenize(tokenizer) for example in examples] + for tokenized_example, expected_tokenized_example in zip( + tokenized_examples, TOKENIZED_TRAIN_EXAMPLES + ): + assert tokenized_example.to_dict() == expected_tokenized_example + + # Testing conversion of a tokenized example to a featurized example + feat_spec = tokenizer.get_feat_spec(max_seq_length=10) + featurized_examples = [ + tokenized_example.featurize(tokenizer=tokenizer, feat_spec=feat_spec) + for tokenized_example in tokenized_examples + ] + featurized_example_0_dict = featurized_examples[0].to_dict() + # not bothering to compare the input_ids because they were made by a dummy tokenizer. + assert "input_ids" in featurized_example_0_dict + assert featurized_example_0_dict["guid"] == FEATURIZED_TRAIN_EXAMPLE_0["guid"] + assert ( + featurized_example_0_dict["input_mask"] == FEATURIZED_TRAIN_EXAMPLE_0["input_mask"] + ).all() + assert ( + featurized_example_0_dict["segment_ids"] == FEATURIZED_TRAIN_EXAMPLE_0["segment_ids"] + ).all() + assert featurized_example_0_dict["label_id"] == FEATURIZED_TRAIN_EXAMPLE_0["label_id"] + assert featurized_example_0_dict["tokens"] == FEATURIZED_TRAIN_EXAMPLE_0["tokens"] diff --git a/tests/tasks/lib/test_wic.py b/tests/tasks/lib/test_wic.py new file mode 100644 index 000000000..74d21793a --- /dev/null +++ b/tests/tasks/lib/test_wic.py @@ -0,0 +1,70 @@ +from collections import Counter + +from jiant.tasks.utils import ExclusiveSpan +from jiant.tasks.lib.wic import Example, TokenizedExample +from jiant.utils.testing.tokenizer import SimpleSpaceTokenizer + + +EXAMPLES = [ + Example( + guid="train-1", + sentence1="Approach a task.", + sentence2="To approach the city.", + word="approach", + span1=ExclusiveSpan(start=0, end=8), + span2=ExclusiveSpan(start=3, end=11), + label=False, + ), + Example( + guid="train-2", + sentence1="In England they call takeout food 'takeaway'.", + sentence2="If you're hungry, there's a takeaway just around the corner.", + word="takeaway", + span1=ExclusiveSpan(start=35, end=43), + span2=ExclusiveSpan(start=28, end=36), + label=True, + ), +] + +TOKENIZED_EXAMPLES = [ + TokenizedExample( + guid="train-1", + sentence1_tokens=["Approach", "a", "task."], + sentence2_tokens=["To", "approach", "the", "city."], + word=["approach"], + sentence1_span=ExclusiveSpan(start=0, end=1), + sentence2_span=ExclusiveSpan(start=1, end=2), + label_id=0, + ), + TokenizedExample( + guid="train-2", + sentence1_tokens=["In", "England", "they", "call", "takeout", "food", "'takeaway'."], + sentence2_tokens=[ + "If", + "you're", + "hungry,", + "there's", + "a", + "takeaway", + "just", + "around", + "the", + "corner.", + ], + word=["takeaway"], + sentence1_span=ExclusiveSpan(start=6, end=7), + sentence2_span=ExclusiveSpan(start=5, end=6), + label_id=1, + ), +] + + +def test_task_tokenization(): + token_counter = Counter() + for example in EXAMPLES: + token_counter.update(example.sentence1.split() + example.sentence2.split()) + token_vocab = list(token_counter.keys()) + tokenizer = SimpleSpaceTokenizer(vocabulary=token_vocab) + + for example, tokenized_example in zip(EXAMPLES, TOKENIZED_EXAMPLES): + assert example.tokenize(tokenizer).to_dict() == tokenized_example.to_dict() diff --git a/tests/tasks/test_mlm.py b/tests/tasks/test_mlm.py deleted file mode 100644 index e1f597e53..000000000 --- a/tests/tasks/test_mlm.py +++ /dev/null @@ -1,102 +0,0 @@ -import unittest -import torch -import random -import copy -import numpy as np -from unittest import mock -from jiant.tasks.registry import REGISTRY -from jiant.modules.sentence_encoder import SentenceEncoder -from jiant.huggingface_transformers_interface.modules import HuggingfaceTransformersEmbedderModule -from jiant.modules.simple_modules import NullPhraseLayer - - -class TestMLM(unittest.TestCase): - def setUp(self): - cls, _, kw = REGISTRY["wikipedia_corpus_mlm"] - self.MLMTask = cls( - "wikipedia_corpus_mlm", - max_seq_len=10, - name="wikipedia_corpus_mlm", - tokenizer_name="roberta-large", - **kw, - ) - args = mock.Mock() - args.input_module = "roberta-large" - args.transformer_max_layer = 0 - args.transfer_paradigm = "finetune" - args.transformers_output_mode = "none" - - args.exp_dir = "" - vocab = mock.Mock() - vocab._padding_token = "" - vocab.get_token_index.side_effect = lambda x: 0 - self.embedder = HuggingfaceTransformersEmbedderModule(args) - self.embedder._mask_id = 3 - self.embedder.model = mock.Mock() - self.embedder.model.config = mock.Mock() - self.embedder.model.config.hidden_size = 100 - self.embedder._pad_id = 0 - self.embedder.max_pos = None - self.embedder._unk_id = 1 - phrase_layer = NullPhraseLayer(512) - self.sent_encoder = SentenceEncoder( - vocab, self.embedder, 1, phrase_layer, skip_embs=0, dropout=0.2, sep_embs_for_skip=1 - ) - - def test_indexing(self): - # Make sure that inputs and labels are consistent with each other - # after the transforms for the indices that are unchanged by - # the dynamic masking. - mask_idx = self.embedder._mask_id - tokenizer_name = "roberta-large" - orig_inputs = torch.LongTensor( - [[4, 100, 30, 459, 2340, 2309, 40, 230, 100, 30, 459, 2340, 2309, 40, 230, 5]] - ) - orig_labels = torch.LongTensor( - [[4, 100, 30, 459, 2340, 2309, 40, 230, 100, 30, 459, 2340, 2309, 40, 230, 5]] - ) - inputs, labels, indices_replaced, _, masked_indices, labels_after_shift = self.MLMTask.mlm_dynamic_masking( - orig_inputs, orig_labels, mask_idx, tokenizer_name, self.sent_encoder - ) - inputs, _ = self.embedder.correct_sent_indexing({"roberta": inputs}) - inputs_unchanged = inputs[~masked_indices] - labels_after_shift = labels_after_shift[~masked_indices] - for input_unchanged, label_shift in zip(inputs_unchanged, labels_after_shift): - assert input_unchanged == label_shift - # Make sure that MASK index is correct in the inputs fed into the model. - mask_inputs = inputs[indices_replaced] - for input in mask_inputs: - assert input == mask_idx - - def test_dynamic_masking(self): - mask_idx = self.embedder._mask_id - tokenizer_name = "roberta-large" - # Generate 10 random input/label combinations and ensure that the indices make sense - # in that the masked indices are approx 0.15 of the input, and indices_replace and indices_random - # are subsets of the masked_indices and mutually exclusive. - masked_ratio = [] - torch.manual_seed(0) - random.seed(0) - for i in range(10): - length = random.randint(10000, 20000) - orig_inputs = torch.LongTensor( - [[4] + [random.randint(0, 10000) for x in range(length)] + [5]] - ) - orig_labels = copy.deepcopy(orig_inputs) - _, _, indices_replaced, indices_random, masked_indices, _ = self.MLMTask.mlm_dynamic_masking( - orig_inputs, orig_labels, mask_idx, tokenizer_name, self.sent_encoder - ) - indices_random = indices_random[0].nonzero().view(-1).numpy().tolist() - indices_replaced = indices_replaced[0].nonzero().view(-1).numpy().tolist() - indices_replaced_random = indices_random + indices_replaced - # Make sure that indices_replaced & indices_random are mutually exclusive - assert ( - len(indices_replaced_random) == (len(indices_random + indices_replaced)) - and len(set(indices_random).intersection(indices_replaced)) == 0 - ) - # Make sure that indices replaced and indices random are in the set of masked_indices - masked_indices = masked_indices[0].nonzero().view(-1).numpy().tolist() - assert set(indices_replaced_random).issubset(set(masked_indices)) - # Make sure that the masking approximately masks ~15% of the input. - masked_ratio.append(float(len(masked_indices)) / float(len(orig_inputs[0]))) - assert np.mean(masked_ratio) >= 0.13 and np.mean(masked_ratio) <= 0.17 diff --git a/tests/tasks/test_sop.py b/tests/tasks/test_sop.py deleted file mode 100644 index 99effc7e2..000000000 --- a/tests/tasks/test_sop.py +++ /dev/null @@ -1,39 +0,0 @@ -import unittest -import tempfile -import os -from jiant.tasks.registry import REGISTRY - - -class TestSOP(unittest.TestCase): - def setUp(self): - cls, _, kw = REGISTRY["wikipedia_corpus_sop"] - self.temp_dir = tempfile.mkdtemp() - self.max_seq_len = 24 - self.SOPTask = cls( - os.path.join("wikipedia_corpus_sop"), - max_seq_len=self.max_seq_len, - name="wikipedia_corpus_sop", - tokenizer_name="roberta-large", - **kw, - ) - os.mkdir(os.path.join(self.temp_dir, "wikipedia_corpus_sop")) - self.train_path = os.path.join(self.temp_dir, "wikipedia_corpus_sop", "train.txt") - with open(self.train_path, "w") as write_fn: - write_fn.write("1Let's see if SOP works. \n") - write_fn.write("1SOP is one of two pretraining objectives. \n") - write_fn.write("1The other one is MLM.") - write_fn.write("=========END OF ARTICLE======== \n") - write_fn.write("2NLP is pretty cool.\n") - write_fn.write("2An area of focus in the NYU lab is transfer learning.\n") - write_fn.write("2There's some pretty cool stuff.") - write_fn.write("=========END OF ARTICLE======== \n") - write_fn.close() - - def test_sop_preprocessing(self): - train_examples = list(self.SOPTask.get_data_iter(self.train_path)) - for example in train_examples: - # This should be same number since seg_A and seg_B are from same document. - assert example[0][0] == example[1][0] - # Make sure END OF ARTICLE is not included as an example. - assert "=" not in "".join(example[0] + example[1]) - assert len(example[0]) + len(example[1]) <= self.max_seq_len - 3 diff --git a/tests/tasks/test_tasks.py b/tests/tasks/test_tasks.py deleted file mode 100644 index 47a24dffd..000000000 --- a/tests/tasks/test_tasks.py +++ /dev/null @@ -1,49 +0,0 @@ -import logging -import unittest - -from jiant.tasks import Task -from jiant.tasks.registry import REGISTRY - - -class TestTasks(unittest.TestCase): - def test_instantiate_all_tasks(self): - """ - All tasks should be able to be instantiated without needing to access actual data - - Test may change if task instantiation signature changes. - """ - logger = logging.getLogger() - logger.setLevel(level=logging.CRITICAL) - for name, (cls, _, kw) in REGISTRY.items(): - cls( - "dummy_path", - max_seq_len=1, - name="dummy_name", - tokenizer_name="dummy_tokenizer_name", - **kw, - ) - - def test_tasks_get_train_instance_iterable_without_phase(self): - task = Task(name="dummy_name", tokenizer_name="dummy_tokenizer_name") - train_iterable = [1, 2, 3] - task.set_instance_iterable("train", train_iterable, "target_train") - self.assertRaises(ValueError, task.get_instance_iterable, "train") - - def test_tasks_set_and_get_instance_iterables(self): - task = Task(name="dummy_name", tokenizer_name="dummy_tokenizer_name") - val_iterable = [1, 2, 3] - test_iterable = [4, 5, 6] - train_pretrain_iterable = [7, 8] - train_target_train_iterable = [9] - task.set_instance_iterable("val", val_iterable) - task.set_instance_iterable("test", test_iterable) - task.set_instance_iterable("train", train_pretrain_iterable, "pretrain") - task.set_instance_iterable("train", train_target_train_iterable, "target_train") - retreived_val_iterable = task.get_instance_iterable("val") - retreived_test_iterable = task.get_instance_iterable("test") - retreived_train_pretrain_iterable = task.get_instance_iterable("train", "pretrain") - retreived_train_target_iterable = task.get_instance_iterable("train", "target_train") - self.assertListEqual(val_iterable, retreived_val_iterable) - self.assertListEqual(test_iterable, retreived_test_iterable) - self.assertListEqual(train_pretrain_iterable, retreived_train_pretrain_iterable) - self.assertListEqual(train_target_train_iterable, retreived_train_target_iterable) diff --git a/tests/test_build_trainer_params.py b/tests/test_build_trainer_params.py deleted file mode 100644 index 5c6f379d9..000000000 --- a/tests/test_build_trainer_params.py +++ /dev/null @@ -1,92 +0,0 @@ -from pkg_resources import resource_filename -import unittest -from unittest import mock -from jiant.trainer import build_trainer_params -from jiant.utils.config import params_from_file -from jiant.__main__ import get_pretrain_stop_metric -from jiant.tasks.registry import REGISTRY - - -class TestBuildTrainerParams(unittest.TestCase): - def setUp(self): - HOCON = """ - lr = 123.456 - pretrain_data_fraction = .123 - target_train_data_fraction = .1234 - mnli = { - lr = 4.56, - batch_size = 123 - max_epochs = 456 - training_data_fraction = .456 - } - qqp = { - max_epochs = 789 - } - """ - DEFAULTS_PATH = resource_filename( - "jiant", "config/defaults.conf" - ) # To get other required values. - params = params_from_file(DEFAULTS_PATH, HOCON) - cuda_device = -1 - self.processed_pretrain_params = build_trainer_params( - params, cuda_device, ["mnli", "qqp"], phase="pretrain" - ) - self.processed_mnli_target_params = build_trainer_params( - params, cuda_device, ["mnli"], phase="target_train" - ) - self.processed_qqp_target_params = build_trainer_params( - params, cuda_device, ["qqp"], phase="target_train" - ) - self.pretrain_tasks = [] - pretrain_task_registry = { - "sst": REGISTRY["sst"], - "winograd-coreference": REGISTRY["winograd-coreference"], - "commitbank": REGISTRY["commitbank"], - } - for name, (cls, _, kw) in pretrain_task_registry.items(): - task = cls( - "dummy_path", max_seq_len=1, name=name, tokenizer_name="dummy_tokenizer_name", **kw - ) - self.pretrain_tasks.append(task) - - def test_pretrain_task_specific(self): - # Task specific trainer parameters shouldn't apply during pretraining. - assert self.processed_pretrain_params["lr"] == 123.456 - assert self.processed_pretrain_params["training_data_fraction"] == 0.123 - assert self.processed_pretrain_params["keep_all_checkpoints"] == 0 # From defaults - - def test_target_task_specific(self): - # Target task parameters should be task specific when possible, and draw on defaults - # otherwise. - assert self.processed_mnli_target_params["lr"] == 4.56 - assert self.processed_qqp_target_params["lr"] == 123.456 - assert self.processed_mnli_target_params["max_epochs"] == 456 - assert self.processed_qqp_target_params["max_epochs"] == 789 - assert self.processed_mnli_target_params["training_data_fraction"] == 0.456 - assert self.processed_qqp_target_params["training_data_fraction"] == 0.1234 - assert self.processed_mnli_target_params["keep_all_checkpoints"] == 0 # From defaults - assert self.processed_qqp_target_params["keep_all_checkpoints"] == 0 # From defaults - - def test_pretrain_stop_metric(self): - self.args = mock.Mock() - self.args.early_stopping_method = "auto" - # Make sure auto case works as expected. - assert ( - get_pretrain_stop_metric(self.args.early_stopping_method, self.pretrain_tasks) - == "macro_avg" - ) - sst_only_pretrain = [self.pretrain_tasks[0]] - assert ( - get_pretrain_stop_metric(self.args.early_stopping_method, sst_only_pretrain) - == "sst_accuracy" - ) - self.args.early_stopping_method = "winograd-coreference" - assert ( - get_pretrain_stop_metric(self.args.early_stopping_method, self.pretrain_tasks) - == "winograd-coreference_acc" - ) - # Case where if we set early_stopping_method to a task that is not included in pretrain_tasks - self.args.early_stopping_method = "sst_accuracy" - pretrain_tasks_no_sst = self.pretrain_tasks[1:] - with self.assertRaises(ValueError): - get_pretrain_stop_metric(self.args.early_stopping_method, pretrain_tasks_no_sst) diff --git a/tests/test_ccg_allignment.py b/tests/test_ccg_allignment.py deleted file mode 100644 index 940afd9f5..000000000 --- a/tests/test_ccg_allignment.py +++ /dev/null @@ -1,78 +0,0 @@ -import csv -import os -import shutil -from string import ascii_lowercase -import tempfile -import unittest - -import pandas as pd - -import scripts.ccg.align_tags_to_bert as ccg_aligner - - -class TestCCGAlignment(unittest.TestCase): - def setUp(self): - self.temp_dir = tempfile.mkdtemp() - self.path = os.path.join(self.temp_dir, "temp_ccg_dataset.tsv") - with open(self.path, "w") as tsvfile: - writer = csv.writer(tsvfile, delimiter="\t") - writer.writerow(["text", "tags"]) - # test for a text that shouldn't be changed by tokenization - writer.writerow(["Influential members of the House", "A B C D E "]) - # test for text that should be changed at the end - writer.writerow( - ["If more information is needed from you Mr. Ford ", "E F G H I J K L M"] - ) - # text for text that should be changed at the beginning - writer.writerow( - ["Mr. Ford if more information is needed from you", "E F G H I J K L M"] - ) - writer.writerow( - ["if more information Mr. Ford is needed from you", "E F G H I J K L M"] - ) - - def test(self): - file = pd.read_csv(self.path, sep="\t") - tag_ids = {ascii_lowercase[i].upper(): i for i in range(len((list(ascii_lowercase))))} - result = ccg_aligner.align_tags_BERT(file, "bert-large-uncased", tag_ids) - assert result.iloc[0]["text"] == file.iloc[0]["text"] - assert result.iloc[0]["tags"].split(" ") == ["0", "1", "2", "3", "4"] - assert result.iloc[1]["tags"].split(" ") == [ - "4", - "5", - "6", - "7", - "8", - "9", - "10", - "11", - "26", - "12", - ] - assert result.iloc[2]["tags"].split(" ") == [ - "4", - "26", - "5", - "6", - "7", - "8", - "9", - "10", - "11", - "12", - ] - assert result.iloc[3]["tags"].split(" ") == [ - "4", - "5", - "6", - "7", - "26", - "8", - "9", - "10", - "11", - "12", - ] - - def tearDown(self): - shutil.rmtree(self.temp_dir) diff --git a/tests/test_checkpointing.py b/tests/test_checkpointing.py deleted file mode 100644 index f46dcc7ce..000000000 --- a/tests/test_checkpointing.py +++ /dev/null @@ -1,280 +0,0 @@ -import csv -import os -import os.path -import shutil -import tempfile -import unittest -from unittest import mock -import torch -import pandas as pd -import glob - -from allennlp.data.token_indexers import SingleIdTokenIndexer -from allennlp.data import Instance, Token, vocabulary -from allennlp.data.fields import LabelField, ListField, MetadataField, TextField -from allennlp.common.params import Params -from allennlp.data.iterators import BasicIterator, BucketIterator -from allennlp.training.learning_rate_schedulers import ( # pylint: disable=import-error - LearningRateScheduler, -) -from allennlp.common.params import Params -from allennlp.training.optimizers import Optimizer -from jiant.allennlp_mods.numeric_field import NumericField - -import jiant.trainer as trainer -from jiant.models import MultiTaskModel -import jiant.tasks.tasks as tasks -from jiant.__main__ import get_best_checkpoint_path - - -def build_trainer_params(args, cuda_device, task_names, phase="pretrain"): - return { - "lr": 1e-05, - "val_data_limit": 10, - "d_hid": 1024, - "min_lr": 0.000, - "max_vals": 4, - "sent_enc": "null", - "scheduler_threshold": 0.0001, - "optimizer": "bert_adam", - "lr_patience": 4, - "lr_decay_factor": 0.05, - "max_grad_norm": 5.0, - "val_interval": 500, - "keep_all_checkpoints": 0, - "max_epochs": 2, - "scheduler_threshold": 0.05, - "patience": 4, - "dec_val_scale": 4, - "training_data_fraction": 1, - "val_interval": 1, - "cuda": cuda_device, - "keep_all_checkpoints": 1, - "accumulation_steps": 1, - } - - -class TestCheckpointing(unittest.TestCase): - def sentence_to_text_field(self, sent, indexers): - """ Helper function to map a sequence of tokens into a sequence of - AllenNLP Tokens, then wrap in a TextField with the given indexers """ - return TextField(list(map(Token, sent)), token_indexers=indexers) - - def setUp(self): - self.temp_dir = tempfile.mkdtemp() - self.path = os.path.join(self.temp_dir, "temp_dataset.tsv") - self.wic = tasks.WiCTask(self.temp_dir, 100, "wic", tokenizer_name="MosesTokenizer") - indexers = {"bert_cased": SingleIdTokenIndexer("bert-xe-cased")} - self.wic.val_data = [ - Instance( - { - "sent1_str": MetadataField("Room and board yo."), - "sent2_str": MetadataField("He nailed boards"), - "idx": LabelField(1, skip_indexing=True), - "idx2": NumericField(2), - "idx1": NumericField(3), - "inputs": self.sentence_to_text_field( - ["[CLS]", "Room", "and", "board", "yo", "[SEP]", "He", "nailed", "boards"], - indexers, - ), - "labels": LabelField(0, skip_indexing=1), - } - ) - ] - self.vocab = vocabulary.Vocabulary.from_instances(self.wic.val_data) - self.vocab.add_token_to_namespace("True", "wic_tags") - for data in self.wic.val_data: - data.index_fields(self.vocab) - self.args = mock.Mock() - self.args.batch_size = 4 - self.args.cuda = -1 - self.args.run_dir = self.temp_dir - self.args.exp_dir = "" - - @mock.patch("jiant.trainer.build_trainer_params", side_effect=build_trainer_params) - def test_checkpointing_does_run(self, build_trainer_params_function): - # Check that checkpointing does run and does sanity checks that at each step - # it saves the most recent checkpoint as well as the best checkpoint - # correctly for both pretrain and target_train stages. - with mock.patch("jiant.models.MultiTaskModel") as MockModel: - import torch - import copy - import time - from allennlp.common.params import Params - - MockModel.return_value.eval.return_value = None - MockModel.return_value.state_dict.return_value = {"model1": {"requires_grad": True}} - pad_dict = self.wic.val_data[0].get_padding_lengths() - sorting_keys = [] - for field in pad_dict: - for pad_field in pad_dict[field]: - sorting_keys.append((field, pad_field)) - iterator = BucketIterator( - sorting_keys=sorting_keys, - max_instances_in_memory=10000, - batch_size=4, - biggest_batch_first=True, - ) - opt_params = Params({"type": "adam", "lr": 1e-05}) - opt_params2 = copy.deepcopy(opt_params) - scheduler_params = Params( - { - "type": "reduce_on_plateau", - "factor": 0.05, - "mode": "max", - "patience": 4, - "threshold": 0.05, - "threshold_mode": "abs", - "verbose": True, - } - ) - train_params = [ - ( - "_text_field_embedder.model.encoder.layer.9.output.dense.bias", - torch.Tensor([0.1, 0.3, 0.4, 0.8]), - ), - ("sent_encoder.layer.1", torch.Tensor([0.1, 0.3, 0.4, 0.8])), - ("type", torch.Tensor([0.1])), - ] - scheduler = LearningRateScheduler.from_params( - Optimizer.from_params(train_params, opt_params2), copy.deepcopy(scheduler_params) - ) - optimizer = Optimizer.from_params(train_params, copy.deepcopy(opt_params)) - _task_infos = { - "wic": { - "iterator": iterator(self.wic.val_data, num_epochs=1), - "n_tr_batches": 1, - "loss": 0.0, - "tr_generator": iterator(self.wic.val_data, num_epochs=1), - "total_batches_trained": 400, - "n_batches_since_val": 0, - "total_steps_trained": 400, - "n_steps_since_val": 0, - "optimizer": optimizer, - "scheduler": scheduler, - "stopped": False, - "last_log": time.time(), - } - } - _metric_infos = { - metric: {"hist": [], "stopped": False, "best": (-1, {})} - for metric in [self.wic.val_metric] - } - MockModel.return_value._setup_training.return_value = _task_infos, _metric_infos - - class MockParams: - def __init__(self, requires_grad): - self.requires_grad = requires_grad - - MockModel.return_value.named_parameters.return_value = [("model1", MockParams(True))] - MockModel.use_bert = 1 - model = MockModel() - cuda_device = -1 - pt_trainer, _, _, _ = trainer.build_trainer( - self.args, - cuda_device, - ["wic"], # here, we use WIC twice to reduce the amount of boiler-plate code - model, - self.args.run_dir, - self.wic.val_metric_decreases, - phase="pretrain", - ) - - tt_trainer, _, _, _ = trainer.build_trainer( - self.args, - cuda_device, - ["wic"], - model, - self.args.run_dir, - self.wic.val_metric_decreases, - phase="target_train", - ) - os.mkdir(os.path.join(self.temp_dir, "wic")) - - tt_trainer.task_to_metric_mapping = {self.wic.val_metric: self.wic.name} - pt_trainer._task_infos = _task_infos - pt_trainer._metric_infos = _metric_infos - pt_trainer._optimizer = optimizer - pt_trainer._scheduler = scheduler - pt_trainer._save_checkpoint( - {"step": 10, "validation_pass": 1, "should_stop": 0}, - tasks=[self.wic], - phase="pretrain", - new_best=True, - ) - pt_trainer._save_checkpoint( - {"step": 10, "validation_pass": 2, "should_stop": 0}, - tasks=[self.wic], - phase="pretrain", - new_best=True, - ) - tt_trainer._task_infos = _task_infos - tt_trainer._metric_infos = _metric_infos - tt_trainer._optimizer = optimizer - tt_trainer._scheduler = scheduler - - tt_trainer._save_checkpoint( - {"step": 10, "validation_pass": 1, "should_stop": 0}, - tasks=[self.wic], - phase="target_train", - new_best=True, - ) - tt_trainer._save_checkpoint( - {"step": 10, "validation_pass": 2, "should_stop": 0}, - tasks=[self.wic], - phase="target_train", - new_best=False, - ) - assert ( - os.path.exists( - os.path.join(self.temp_dir, "wic", "model_state_target_train_val_1.best.th") - ) - and os.path.exists( - os.path.join(self.temp_dir, "wic", "model_state_target_train_val_2.th") - ) - and os.path.exists( - os.path.join(self.temp_dir, "model_state_pretrain_val_2.best.th") - ) - and os.path.exists(os.path.join(self.temp_dir, "model_state_pretrain_val_1.th")) - ) - - # Assert only one checkpoint is created for pretrain stage. - pretrain_best_checkpoints = glob.glob( - os.path.join(self.temp_dir, "model_state_pretrain_val_*.best.th") - ) - assert len(pretrain_best_checkpoints) == 1 - - def test_get_best_checkpointing(self): - """ - Testing the get_best_checkpointing function for path logic. - """ - self.args.load_target_train_checkpoint = os.path.join(self.temp_dir, "target_checkpoint") - self.args.load_eval_checkpoint = "" - open(self.args.load_target_train_checkpoint, "wb").close() - target_ckpt = get_best_checkpoint_path(self.args, phase="target_train", task_name=None) - assert target_ckpt == self.args.load_target_train_checkpoint - - # Load from best pretrain checkpoint. - self.args.load_target_train_checkpoint = "" - os.mkdir(os.path.join(self.temp_dir, "wic")) - best_pretrain_path = os.path.join(self.temp_dir, "model_state_pretrain_val_1.best.th") - open(best_pretrain_path, "wb").close() - target_ckpt = get_best_checkpoint_path(self.args, phase="target_train", task_name=None) - assert target_ckpt == best_pretrain_path - - # Load from the best target train phase checkpoint. - best_target_train_path = os.path.join( - self.temp_dir, "wic", "model_state_target_train_val_1.best.th" - ) - open(best_target_train_path, "wb").close() - target_ckpt = get_best_checkpoint_path(self.args, phase="eval", task_name="wic") - assert target_ckpt == best_target_train_path - - # Load from pre-existing eval checkpoint. - self.args.load_eval_checkpoint = str(os.path.join(self.temp_dir, "eval_checkpoint")) - open(self.args.load_eval_checkpoint, "wb").close() - target_ckpt = get_best_checkpoint_path(self.args, phase="eval", task_name="wic") - target_ckpt == self.args.load_eval_checkpoint - - def tearDown(self): - shutil.rmtree(self.temp_dir) diff --git a/tests/test_gradient_accumulation.py b/tests/test_gradient_accumulation.py deleted file mode 100644 index 022e73fbb..000000000 --- a/tests/test_gradient_accumulation.py +++ /dev/null @@ -1,65 +0,0 @@ -import tempfile - -from pkg_resources import resource_filename -import unittest -from unittest import mock - -from jiant.__main__ import check_configurations -from jiant.tasks import tasks -from jiant.trainer import build_trainer -from jiant.utils.config import params_from_file - - -class TestGradientAccumulation(unittest.TestCase): - def setUp(self): - self.temp_dir = tempfile.mkdtemp() - self.wic = tasks.WiCTask(self.temp_dir, 100, "wic", tokenizer_name="MosesTokenizer") - - def test_steps_between_gradient_accumulations_must_be_defined(self): - self.args = params_from_file(resource_filename("jiant", "config/defaults.conf")) - del self.args.accumulation_steps - self.assertRaises(AssertionError, check_configurations, self.args, [], []) - - def test_steps_between_gradient_accumulations_cannot_be_set_to_a_negative_number(self): - self.args = params_from_file( - resource_filename("jiant", "config/defaults.conf"), "accumulation_steps = -1" - ) - self.assertRaises(AssertionError, check_configurations, self.args, [], []) - - def test_by_default_steps_between_gradient_accumulations_is_set_to_1(self): - with mock.patch("jiant.models.MultiTaskModel") as MockModel: - self.args = params_from_file(resource_filename("jiant", "config/defaults.conf")) - self.args.cuda = -1 - self.args.run_dir = self.temp_dir - self.args.exp_dir = self.temp_dir - model = MockModel() - _, train_params, _, _ = build_trainer( - self.args, - self.args.cuda, - ["wic"], - model, - self.args.run_dir, - self.wic.val_metric_decreases, - phase="pretrain", - ) - self.assertEqual(train_params["accumulation_steps"], 1) - - def test_steps_between_gradient_accumulations_can_be_overridden_and_set_greater_than_1(self): - with mock.patch("jiant.models.MultiTaskModel") as MockModel: - self.args = params_from_file( - resource_filename("jiant", "config/defaults.conf"), "accumulation_steps = 10" - ) - self.args.cuda = -1 - self.args.run_dir = self.temp_dir - self.args.exp_dir = self.temp_dir - model = MockModel() - _, train_params, _, _ = build_trainer( - self.args, - self.args.cuda, - ["wic"], - model, - self.args.run_dir, - self.wic.val_metric_decreases, - phase="pretrain", - ) - self.assertEqual(train_params["accumulation_steps"], 10) diff --git a/tests/test_huggingface_transformers_interface.py b/tests/test_huggingface_transformers_interface.py deleted file mode 100644 index de5e0dc7e..000000000 --- a/tests/test_huggingface_transformers_interface.py +++ /dev/null @@ -1,191 +0,0 @@ -import unittest -from unittest import mock -import torch -import copy -from jiant.huggingface_transformers_interface.modules import ( - HuggingfaceTransformersEmbedderModule, - BertEmbedderModule, - RobertaEmbedderModule, - AlbertEmbedderModule, - XLNetEmbedderModule, - OpenAIGPTEmbedderModule, - GPT2EmbedderModule, - TransfoXLEmbedderModule, - XLMEmbedderModule, -) - - -class TestHuggingfaceTransformersInterface(unittest.TestCase): - def test_bert_apply_boundary_tokens(self): - s1 = ["A", "B", "C"] - s2 = ["D", "E"] - self.assertListEqual( - BertEmbedderModule.apply_boundary_tokens(s1), ["[CLS]", "A", "B", "C", "[SEP]"] - ) - self.assertListEqual( - BertEmbedderModule.apply_boundary_tokens(s1, s2), - ["[CLS]", "A", "B", "C", "[SEP]", "D", "E", "[SEP]"], - ) - - def test_roberta_apply_boundary_tokens(self): - s1 = ["A", "B", "C"] - s2 = ["D", "E"] - self.assertListEqual( - RobertaEmbedderModule.apply_boundary_tokens(s1), ["", "A", "B", "C", ""] - ) - self.assertListEqual( - RobertaEmbedderModule.apply_boundary_tokens(s1, s2), - ["", "A", "B", "C", "", "
", "D", "E", ""], - ) - - def test_albert_apply_boundary_tokens(self): - s1 = ["A", "B", "C"] - s2 = ["D", "E"] - self.assertListEqual( - AlbertEmbedderModule.apply_boundary_tokens(s1), ["[CLS]", "A", "B", "C", "[SEP]"] - ) - self.assertListEqual( - AlbertEmbedderModule.apply_boundary_tokens(s1, s2), - ["[CLS]", "A", "B", "C", "[SEP]", "D", "E", "[SEP]"], - ) - - def test_xlnet_apply_boundary_tokens(self): - s1 = ["A", "B", "C"] - s2 = ["D", "E"] - self.assertListEqual( - XLNetEmbedderModule.apply_boundary_tokens(s1), ["A", "B", "C", "", ""] - ) - self.assertListEqual( - XLNetEmbedderModule.apply_boundary_tokens(s1, s2), - ["A", "B", "C", "", "D", "E", "", ""], - ) - - def test_gpt_apply_boundary_tokens(self): - s1 = ["A", "B", "C"] - s2 = ["D", "E"] - self.assertListEqual( - OpenAIGPTEmbedderModule.apply_boundary_tokens(s1), - ["", "A", "B", "C", ""], - ) - self.assertListEqual( - OpenAIGPTEmbedderModule.apply_boundary_tokens(s1, s2), - ["", "A", "B", "C", "", "D", "E", ""], - ) - - def test_xlm_apply_boundary_tokens(self): - s1 = ["A", "B", "C"] - s2 = ["D", "E"] - self.assertListEqual( - XLMEmbedderModule.apply_boundary_tokens(s1), ["", "A", "B", "C", ""] - ) - self.assertListEqual( - XLMEmbedderModule.apply_boundary_tokens(s1, s2), - ["", "A", "B", "C", "", "D", "E", ""], - ) - - def test_correct_sent_indexing(self): - model = mock.Mock() - model._pad_id = 7 - model._unk_id = 10 - model.max_pos = None - model.tokenizer_required = "correct_tokenizer" - model.correct_sent_indexing = HuggingfaceTransformersEmbedderModule.correct_sent_indexing - - allenNLP_indexed = torch.LongTensor([[7, 10, 5, 11, 1, 13, 5], [7, 10, 11, 5, 1, 5, 0]]) - - expected_ids = torch.LongTensor([[5, 8, 3, 9, 10, 11, 3], [5, 8, 9, 3, 10, 3, 7]]) - expected_mask = torch.LongTensor([[1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 0]]) - - # test the required_tokenizer assertion(bad case) - assertionerror_found = False - sent = {"wrong_tokenizer": copy.deepcopy(allenNLP_indexed)} - try: - model.correct_sent_indexing(model, sent) - except AssertionError: - assertionerror_found = True - assert assertionerror_found - - # test the required_tokenizer, unk_id assertion(good case) - # test the result correctness - sent = {"correct_tokenizer": copy.deepcopy(allenNLP_indexed)} - ids, input_mask = model.correct_sent_indexing(model, sent) - assert torch.all(torch.eq(ids, expected_ids)) - assert torch.all(torch.eq(input_mask, expected_mask)) - - # test the unk_id assertion(bad case) - model._unk_id = None - assertionerror_found = False - sent = {"correct_tokenizer": copy.deepcopy(allenNLP_indexed)} - try: - model.correct_sent_indexing(model, sent) - except AssertionError: - assertionerror_found = True - assert assertionerror_found - model._unk_id = 10 - - # test the max input length assertion(bad case) - model.max_pos = 6 - assertionerror_found = False - sent = {"correct_tokenizer": copy.deepcopy(allenNLP_indexed)} - try: - model.correct_sent_indexing(model, sent) - except AssertionError: - assertionerror_found = True - assert assertionerror_found - - # test the max input length assertion(good case) - model.max_pos = 7 - sent = {"correct_tokenizer": copy.deepcopy(allenNLP_indexed)} - ids, input_mask = model.correct_sent_indexing(model, sent) - assert torch.all(torch.eq(ids, expected_ids)) - assert torch.all(torch.eq(input_mask, expected_mask)) - - def test_bert_seg_ids(self): - bert_model = mock.Mock() - bert_model._sep_id = 3 - bert_model._cls_id = 5 - bert_model._pad_id = 7 - bert_model._SEG_ID_CLS = None - bert_model._SEG_ID_SEP = None - bert_model.get_seg_ids = BertEmbedderModule.get_seg_ids - - # [CLS] 8 [SEP] 9 10 11 [SEP] - # [CLS] 8 9 [SEP] 10 [SEP] [PAD] - inp = torch.LongTensor([[5, 8, 3, 9, 10, 11, 3], [5, 8, 9, 3, 10, 3, 7]]) - mask = inp != bert_model._pad_id - output = bert_model.get_seg_ids(bert_model, inp, mask.long()) - assert torch.all( - torch.eq(output, torch.LongTensor([[0, 0, 0, 1, 1, 1, 1], [0, 0, 0, 0, 1, 1, 0]])) - ) - - # [CLS] 8 9 [SEP] - # [CLS] 8 [SEP] [PAD] - inp = torch.LongTensor([[5, 8, 9, 3], [5, 9, 3, 7]]) - mask = inp != bert_model._pad_id - output = bert_model.get_seg_ids(bert_model, inp, mask.long()) - assert torch.all(torch.eq(output, torch.LongTensor([[0, 0, 0, 0], [0, 0, 0, 0]]))) - - def test_xlnet_seg_ids(self): - xlnet_model = mock.Mock() - xlnet_model._sep_id = 3 - xlnet_model._cls_id = 5 - xlnet_model._pad_id = 7 - xlnet_model._SEG_ID_CLS = 2 - xlnet_model._SEG_ID_SEP = 3 - xlnet_model.get_seg_ids = XLNetEmbedderModule.get_seg_ids - - # 8 [SEP] 9 10 11 [SEP] [CLS] - # 8 [SEP] 9 10 [SEP] [CLS] [PAD] - inp = torch.LongTensor([[8, 3, 9, 10, 11, 3, 5], [8, 3, 9, 10, 3, 5, 7]]) - mask = inp != xlnet_model._pad_id - output = xlnet_model.get_seg_ids(xlnet_model, inp, mask.long()) - assert torch.all( - torch.eq(output, torch.LongTensor([[0, 3, 1, 1, 1, 3, 2], [0, 3, 1, 1, 3, 2, 0]])) - ) - - # 8 9 10 [SEP] [CLS] - # 8 9 [SEP] [CLS] [PAD] - inp = torch.LongTensor([[8, 9, 10, 3, 5], [8, 9, 3, 5, 7]]) - mask = inp != xlnet_model._pad_id - output = xlnet_model.get_seg_ids(xlnet_model, inp, mask.long()) - assert torch.all(torch.eq(output, torch.LongTensor([[0, 0, 0, 3, 2], [0, 0, 3, 2, 0]]))) diff --git a/tests/test_logging_utils.py b/tests/test_logging_utils.py deleted file mode 100644 index 178177644..000000000 --- a/tests/test_logging_utils.py +++ /dev/null @@ -1,69 +0,0 @@ -import csv -import os -import shutil -import tempfile -import unittest -import pyhocon -import jsondiff - -import jiant.utils.utils as utils - - -class TestParseJsonDiff(unittest.TestCase): - def test_replace_insert_parse_json_diff(self): - output_diff = { - "mrpc": { - jsondiff.replace: pyhocon.ConfigTree( - [ - ("classifier_dropout", 0.1), - ("classifier_hid_dim", 256), - ("max_vals", 8), - ("val_interval", 1), - ] - ) - } - } - parsed_diff = utils.parse_json_diff(output_diff) - assert isinstance(parsed_diff["mrpc"], pyhocon.ConfigTree) - output_diff = { - "mrpc": { - jsondiff.insert: pyhocon.ConfigTree( - [ - ("classifier_dropout", 0.1), - ("classifier_hid_dim", 256), - ("max_vals", 8), - ("val_interval", 1), - ] - ) - } - } - parsed_diff = utils.parse_json_diff(output_diff) - assert isinstance(parsed_diff["mrpc"], pyhocon.ConfigTree) - - def test_delete_parse_json_diff(self): - output_diff = {"mrpc": {jsondiff.delete: [1], "lr": 0.001}} - parsed_diff = utils.parse_json_diff(output_diff) - assert jsondiff.delete not in parsed_diff["mrpc"].keys() - - -class TestSortRecursively(unittest.TestCase): - def test_replace_insert_parse_json_diff(self): - input_diff = { - "mrpc": pyhocon.ConfigTree( - [ - ("classifier_hid_dim", 256), - ("max_vals", 8), - ("classifier_dropout", 0.1), - ("val_interval", 1), - ] - ), - "rte": {"configs": pyhocon.ConfigTree([("b", 1), ("a", 3)])}, - } - sorted_diff = utils.sort_param_recursive(input_diff) - assert list(sorted_diff["mrpc"].items()) == [ - ("classifier_dropout", 0.1), - ("classifier_hid_dim", 256), - ("max_vals", 8), - ("val_interval", 1), - ] - assert list(sorted_diff["rte"]["configs"].items()) == [("a", 3), ("b", 1)] diff --git a/tests/test_models.py b/tests/test_models.py deleted file mode 100644 index 8e9787f80..000000000 --- a/tests/test_models.py +++ /dev/null @@ -1,6 +0,0 @@ -import unittest - - -class TestModel(unittest.TestCase): - def test_import(self): - from jiant.models import build_model diff --git a/tests/test_nli_metric.py b/tests/test_nli_metric.py deleted file mode 100644 index 032f70cac..000000000 --- a/tests/test_nli_metric.py +++ /dev/null @@ -1,54 +0,0 @@ -import unittest -import torch - -from jiant.metrics.nli_metrics import NLITwoClassAccuracy - - -class TestNLIMetric(unittest.TestCase): - def test_two_class_acc_w_two_class_data_and_model(self): - nli_scorer = NLITwoClassAccuracy() - - # Note: predictions are of shape num_batches x batch_size x num_classes - predictions = torch.Tensor([[[0, 1], [0, 1]], [[1, 0], [1, 0]]]) - true_labels = torch.Tensor([[1, 1], [0, 0]]) - nli_scorer(predictions, true_labels) - acc = nli_scorer.get_metric(reset=True) - assert acc == 1.0 - - predictions = torch.Tensor([[[1, 0], [1, 0]], [[1, 0], [0, 1]]]) - true_labels = torch.Tensor([[1, 1], [0, 0]]) - nli_scorer(predictions, true_labels) - acc = nli_scorer.get_metric(reset=True) - assert acc == 1.0 / 4.0 - - def test_two_class_acc_w_two_class_data(self): - nli_scorer = NLITwoClassAccuracy() - - # Note: predictions are of shape num_batches x batch_size x num_classes - predictions = torch.Tensor([[[0, 1, 0], [0, 1, 0]], [[0, 0, 1], [1, 0, 0]]]) - true_labels = torch.Tensor([[1, 1], [0, 0]]) - nli_scorer(predictions, true_labels) - acc = nli_scorer.get_metric(reset=True) - assert acc == 1.0 - - predictions = torch.Tensor([[[1, 0, 0], [1, 0, 0]], [[0, 0, 1], [0, 1, 0]]]) - true_labels = torch.Tensor([[1, 1], [0, 0]]) - nli_scorer(predictions, true_labels) - acc = nli_scorer.get_metric(reset=True) - assert acc == 1.0 / 4.0 - - def test_two_class_acc_w_two_class_model(self): - nli_scorer = NLITwoClassAccuracy() - - # Note: predictions are of shape num_batches x batch_size x num_classes - predictions = torch.Tensor([[[0, 1], [0, 1]], [[1, 0], [1, 0]]]) - true_labels = torch.Tensor([[1, 1], [2, 0]]) - nli_scorer(predictions, true_labels) - acc = nli_scorer.get_metric(reset=True) - assert acc == 1.0 - - predictions = torch.Tensor([[[1, 0], [1, 0]], [[1, 0], [0, 1]]]) - true_labels = torch.Tensor([[1, 1], [2, 0]]) - nli_scorer(predictions, true_labels) - acc = nli_scorer.get_metric(reset=True) - assert acc == 1.0 / 4.0 diff --git a/tests/test_preprocess.py b/tests/test_preprocess.py deleted file mode 100644 index ef95a8031..000000000 --- a/tests/test_preprocess.py +++ /dev/null @@ -1,77 +0,0 @@ -import csv -import os -import os.path -from pkg_resources import resource_filename -import shutil -import tempfile -import unittest -from unittest import mock - -import jiant.tasks.tasks as tasks -from jiant.utils.config import params_from_file -from jiant.preprocess import get_task_without_loading_data, build_indexers, get_vocab - - -class TestProprocess(unittest.TestCase): - def setUp(self): - self.HOCON1 = """ - pretrain_tasks = mnli - target_tasks = qqp - tokenizer = bert-large-cased - input_module = bert-large-cased - """ - self.HOCON2 = """ - pretrain_task s= mnli - target_tasks = qqp - input_module = glove - tokenizer = MosesTokenizer - """ - self.HOCON3 = """ - pretrain_task s= mnli - target_tasks = qqp - input_module = openai-gpt - tokenizer = openai-gpt - """ - self.HOCON4 = """ - pretrain_tasks = mnli - target_tasks = qqp - tokenizer = bert-large-cased - input_module = bert-base-cased - """ - self.DEFAULTS_PATH = resource_filename( - "jiant", "config/defaults.conf" - ) # To get other required values. - self.params1 = params_from_file(self.DEFAULTS_PATH, self.HOCON1) - - def test_get_task_without_loading_data(self): - # Test task laoding. - tasks = get_task_without_loading_data("mnli", self.params1) - assert tasks.name == "mnli" - - def test_build_indexers(self): - self.params2 = params_from_file(self.DEFAULTS_PATH, self.HOCON2) - self.params3 = params_from_file(self.DEFAULTS_PATH, self.HOCON3) - self.params4 = params_from_file(self.DEFAULTS_PATH, self.HOCON4) - indexer = build_indexers(self.params1) - len(indexer) == 1 and list(indexer.keys())[0] == "bert_cased" - indexer = build_indexers(self.params2) - len(indexer) == 1 and list(indexer.keys())[0] == "words" - indexer = build_indexers(self.params3) - len(indexer) == 1 and list(indexer.keys())[0] == "openai_gpt" - with self.assertRaises(AssertionError) as error: - # BERT model and tokenizer must be equal, so this should throw an error. - indexer = build_indexers(self.params4) - - def test_build_vocab(self): - word2freq = {"first": 100, "second": 5, "third": 10} - char2freq = {"a": 10, "b": 100, "c": 30} - max_vocab_size = {"word": 2, "char": 3} - vocab = get_vocab(word2freq, char2freq, max_vocab_size) - assert len(vocab.get_index_to_token_vocabulary("tokens")) == 6 - assert set(vocab.get_index_to_token_vocabulary("tokens").values()) == set( - ["@@PADDING@@", "@@UNKNOWN@@", "", "", "first", "third"] - ) - assert len(vocab.get_index_to_token_vocabulary("chars")) == 5 - assert set(vocab.get_index_to_token_vocabulary("chars").values()) == set( - ["@@PADDING@@", "@@UNKNOWN@@", "a", "b", "c"] - ) diff --git a/tests/test_preprocess_winograd.py b/tests/test_preprocess_winograd.py deleted file mode 100644 index 12141c3c4..000000000 --- a/tests/test_preprocess_winograd.py +++ /dev/null @@ -1,120 +0,0 @@ -import csv -import os -import pandas as pd -import shutil -import tempfile -import unittest -import jiant.utils.retokenize as retokenize -import json -import copy - -""" -Tests scripts/winograd/preprocess_winograd.py. -""" - - -class TestPreprocessWinograd(unittest.TestCase): - def setUp(self): - self.temp_dir = tempfile.mkdtemp() - self.path = os.path.join(self.temp_dir, "temp_winograd_dataset.tsv") - with open(self.path, "w") as jsonfile: - - # test for a indices that shouldn't be changed by tokenization - jsonfile.write( - json.dumps( - { - "text": "Members of the House clapped their hands", - "target": { - "span1_index": 0, - "span1_text": "members", - "span2_index": 5, - "span2_text": "their", - "label": True, - }, - } - ) - ) - jsonfile.write("\n") - # test where both span indices should shift - jsonfile.write( - json.dumps( - { - "text": "Mr. Ford told me to tell you to contact him", - "target": { - "span1_index": 0, - "span1_text": "Mr. Ford", - "span2_index": 9, - "span2_text": "him", - "label": True, - }, - } - ) - ) - jsonfile.write("\n") - # test where only one of the span indices changes - jsonfile.write( - json.dumps( - { - "text": "I told you already, Mr. Ford!", - "target": { - "span1_index": 4, - "span1_text": "Mr. Ford", - "span2_index": 0, - "span2_text": "I", - "label": False, - }, - } - ) - ) - jsonfile.write("\n") - jsonfile.write( - json.dumps( - { - "text": "I look at Sarah's dog. It was cute.!", - "target": { - "span1_index": 3, - "span1_text": "Sarah's dog.", - "span2_index": 0, - "span2_text": "I", - "label": False, - }, - } - ) - ) - - def test_bert(self): - records = list(pd.read_json(self.path, lines=True).T.to_dict().values()) - orig_records = copy.deepcopy(records) - for rec in records[:-1]: - retokenize.realign_spans(rec, "bert-large-cased") - retokenize.realign_spans(records[-1], "MosesTokenizer") - assert records[0]["text"] == orig_records[0]["text"] - # the two below should be changed by tokenization - assert records[1]["text"] != orig_records[1]["text"] - assert records[2]["text"] != orig_records[2]["text"] - - result_span1 = records[0]["target"]["span1"] - result_span2 = records[0]["target"]["span2"] - assert result_span1 == [0, 1] - assert result_span2 == [5, 6] - - result_span1 = records[1]["target"]["span1"] - result_span2 = records[1]["target"]["span2"] - - assert result_span1 == [0, 3] - assert result_span2 == [10, 11] - - result_span1 = records[2]["target"]["span1"] - result_span2 = records[2]["target"]["span2"] - - assert result_span1 == [5, 9] - assert result_span2 == [0, 1] - - result_span1 = records[3]["target"]["span1"] - result_span2 = records[3]["target"]["span2"] - - assert result_span1 == [3, 7] - assert result_span2 == [0, 1] - - def tearDown(self): - shutil.rmtree(self.temp_dir) diff --git a/tests/test_restore_runs.py b/tests/test_restore_runs.py deleted file mode 100644 index 9bb403c61..000000000 --- a/tests/test_restore_runs.py +++ /dev/null @@ -1,129 +0,0 @@ -import os -import os.path -import shutil -import tempfile -import unittest -from unittest import mock - -from jiant import evaluate -import jiant.tasks.tasks as tasks -from jiant.utils import utils -from jiant.__main__ import evaluate_and_write, get_best_checkpoint_path - - -class TestRestoreRuns(unittest.TestCase): - def setUp(self): - self.temp_dir = tempfile.mkdtemp() - self.mrpc = tasks.MRPCTask(self.temp_dir, 100, "mrpc", tokenizer_name="MosesTokenizer") - self.sst = tasks.MRPCTask(self.temp_dir, 100, "sst", tokenizer_name="MosesTokenizer") - os.mkdir(os.path.join(self.temp_dir, "mrpc")) - os.mkdir(os.path.join(self.temp_dir, "sst")) - for type_name in ["model", "task", "training", "metric"]: - open( - os.path.join(self.temp_dir, "{}_state_pretrain_val_1.th".format(type_name)), "w" - ).close() - open( - os.path.join(self.temp_dir, "{}_state_pretrain_val_2.th".format(type_name)), "w" - ).close() - open( - os.path.join(self.temp_dir, "{}_state_pretrain_val_3.best.th".format(type_name)), - "w", - ).close() - open( - os.path.join( - self.temp_dir, "mrpc", "{}_state_target_train_val_1.best.th".format(type_name) - ), - "w", - ).close() - open( - os.path.join( - self.temp_dir, "mrpc", "{}_state_target_train_val_2.th".format(type_name) - ), - "w", - ).close() - - def test_check_for_previous_checkpoints(self): - # Testing that check_for_previous_checkpoints returns the correct checkpoints given - # the state of a run directory. - tasks = [self.mrpc, self.sst] - task_directory, max_epoch, suffix = utils.check_for_previous_checkpoints( - self.temp_dir, tasks, phase="pretrain", load_model=True - ) - assert task_directory == "" and max_epoch == 3 and suffix == "state_pretrain_val_3.best.th" - task_directory, max_epoch, suffix = utils.check_for_previous_checkpoints( - self.temp_dir, tasks, phase="target_train", load_model=True - ) - assert ( - task_directory == "mrpc" and max_epoch == 2 and suffix == "state_target_train_val_2.th" - ) - # Test partial checkpoints. - # If <4 checkpoints are found for an epoch, we do not count that epoch as - # the most recent. - for type_name in ["model", "task"]: - open( - os.path.join( - self.temp_dir, "sst", "{}_state_target_train_val_1.best.th".format(type_name) - ), - "w", - ).close() - task_directory, max_epoch, suffix = utils.check_for_previous_checkpoints( - self.temp_dir, tasks, phase="target_train", load_model=True - ) - # Even though there are partial checkpoints in the sst directory, - # it still will return the most recent checkpoint as in mrpc. - assert ( - task_directory == "mrpc" and max_epoch == 2 and suffix == "state_target_train_val_2.th" - ) - for type_name in ["training", "metric"]: - open( - os.path.join( - self.temp_dir, "sst", "{}_state_target_train_val_1.best.th".format(type_name) - ), - "w", - ).close() - open( - os.path.join( - self.temp_dir, "sst", "{}_state_target_train_val_2.best.th".format(type_name) - ), - "w", - ).close() - task_directory, max_epoch, suffix = utils.check_for_previous_checkpoints( - self.temp_dir, tasks, phase="target_train", load_model=True - ) - # Now that there is a complete set of 4 checkpoints in the sst directory, - # the function should return sst as the directory with the most recent - # checkpoint. - assert ( - task_directory == "sst" - and max_epoch == 1 - and suffix == "state_target_train_val_1.best.th" - ) - - def test_check_for_previous_ckpt_assert(self): - # Testing that if args.load_model=0 and there are checkpoints in pretrain or target_train, - # check_for_previous_checkpoints throws an error. - with self.assertRaises(AssertionError) as error: - utils.check_for_previous_checkpoints( - self.temp_dir, tasks, phase="pretrain", load_model=False - ) - utils.check_for_previous_checkpoints( - self.temp_dir, tasks, phase="target_train", load_model=False - ) - - def test_find_last_checkpoint_epoch(self): - # Testing path-finding logic of find_last_checkpoint_epoch function. - max_epoch, suffix = utils.find_last_checkpoint_epoch( - self.temp_dir, search_phase="pretrain", task_name="" - ) - assert max_epoch == 3 and suffix == "state_pretrain_val_3.best.th" - max_epoch, suffix = utils.find_last_checkpoint_epoch( - self.temp_dir, search_phase="target_train", task_name="sst" - ) - assert max_epoch == -1 and suffix is None - max_epoch, suffix = utils.find_last_checkpoint_epoch( - self.temp_dir, search_phase="target_train", task_name="mrpc" - ) - assert max_epoch == 2 and suffix == "state_target_train_val_2.th" - - def tearDown(self): - shutil.rmtree(self.temp_dir) diff --git a/tests/test_retokenize.py b/tests/test_retokenize.py deleted file mode 100644 index b512651a9..000000000 --- a/tests/test_retokenize.py +++ /dev/null @@ -1,349 +0,0 @@ -import unittest -import jiant.utils.retokenize as retokenize - - -class TestRetokenize(unittest.TestCase): - def setUp(self): - self.text = [ - "Members of the House clapped their hands", - "I look at Sarah's dog. It was cute.!", - "Mr. Immelt chose to focus on the incomprehensibility of accounting rules.", - "What?", - ] - self.token_index_src = [ - [0, 1, 2, 3, 4, 5, 6], - [0, 1, 2, 3, 4, 5, 6, 7], - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], - [0], - ] - self.span_index_src = [ - [(0, 4), (5, 7)], - [(0, 1), (3, 5)], - [(0, 2), (6, 11), (6, 8), (7, 11)], - [(0, 1)], - ] - - def test_moses(self): - self.tokens = [ - ["Members", "of", "the", "House", "clapped", "their", "hands"], - ["I", "look", "at", "Sarah", "'s", "dog", ".", "It", "was", "cute", ".", "!"], - [ - "Mr.", - "Immelt", - "chose", - "to", - "focus", - "on", - "the", - "incomprehensibility", - "of", - "accounting", - "rules", - ".", - ], - ["What", "?"], - ] - self.token_index_tgt = [ - [[0], [1], [2], [3], [4], [5], [6]], - [[0], [1], [2], [3, 4], [5, 6], [7], [8], [9, 10, 11]], - [[0], [1], [2], [3], [4], [5], [6], [7], [8], [9], [10, 11]], - [[0, 1]], - ] - self.span_index_tgt = [ - [(0, 4), (5, 7)], - [(0, 1), (3, 7)], - [(0, 2), (6, 12), (6, 8), (7, 12)], - [(0, 2)], - ] - - aligner_fn = retokenize.get_aligner_fn("transfo-xl-wt103") - token_aligners, tokens = zip(*(aligner_fn(sent) for sent in self.text)) - token_aligners, tokens = list(token_aligners), list(tokens) - token_index_tgt = [ - [token_aligner.project_tokens(idxs).tolist() for idxs in token_idxs] - for token_aligner, token_idxs in zip(token_aligners, self.token_index_src) - ] - span_index_tgt = [ - [token_aligner.project_span(start, end) for (start, end) in span_idxs] - for token_aligner, span_idxs in zip(token_aligners, self.span_index_src) - ] - assert self.tokens == tokens - assert self.token_index_tgt == token_index_tgt - assert self.span_index_tgt == span_index_tgt - - def test_wpm(self): - self.tokens = [ - ["Members", "of", "the", "House", "clapped", "their", "hands"], - ["I", "look", "at", "Sarah", "'", "s", "dog", ".", "It", "was", "cute", ".", "!"], - [ - "Mr", - ".", - "I", - "##mme", - "##lt", - "chose", - "to", - "focus", - "on", - "the", - "in", - "##com", - "##p", - "##re", - "##hen", - "##si", - "##bility", - "of", - "accounting", - "rules", - ".", - ], - ["What", "?"], - ] - self.token_index_tgt = [ - [[0], [1], [2], [3], [4], [5], [6]], - [[0], [1], [2], [3, 4, 5], [6, 7], [8], [9], [10, 11, 12]], - [ - [0, 1], - [2, 3, 4], - [5], - [6], - [7], - [8], - [9], - [10, 11, 12, 13, 14, 15, 16], - [17], - [18], - [19, 20], - ], - [[0, 1]], - ] - self.span_index_tgt = [ - [(0, 4), (5, 7)], - [(0, 1), (3, 8)], - [(0, 5), (9, 21), (9, 17), (10, 21)], - [(0, 2)], - ] - - aligner_fn = retokenize.get_aligner_fn("bert-base-cased") - token_aligners, tokens = zip(*(aligner_fn(sent) for sent in self.text)) - token_aligners, tokens = list(token_aligners), list(tokens) - token_index_tgt = [ - [token_aligner.project_tokens(idxs).tolist() for idxs in token_idxs] - for token_aligner, token_idxs in zip(token_aligners, self.token_index_src) - ] - span_index_tgt = [ - [token_aligner.project_span(start, end) for (start, end) in span_idxs] - for token_aligner, span_idxs in zip(token_aligners, self.span_index_src) - ] - assert self.tokens == tokens - assert self.token_index_tgt == token_index_tgt - assert self.span_index_tgt == span_index_tgt - - def test_bpe(self): - self.tokens = [ - [ - "members", - "of", - "the", - "house", - "clapped", - "their", - "hands", - ], - [ - "i", - "look", - "at", - "sarah", - "'s", - "dog", - ".", - "it", - "was", - "cute", - ".", - "!", - ], - [ - "mr.", - "im", - "melt", - "chose", - "to", - "focus", - "on", - "the", - "in", - "comprehen", - "si", - "bility", - "of", - "accounting", - "rules", - ".", - ], - ["what", "?"], - ] - self.token_index_tgt = [ - [[0], [1], [2], [3], [4], [5], [6]], - [[0], [1], [2], [3, 4], [5, 6], [7], [8], [9, 10, 11]], - [[0], [1, 2], [3], [4], [5], [6], [7], [8, 9, 10, 11], [12], [13], [14, 15]], - [[0, 1]], - ] - self.span_index_tgt = [ - [(0, 4), (5, 7)], - [(0, 1), (3, 7)], - [(0, 3), (7, 16), (7, 12), (8, 16)], - [(0, 2)], - ] - - aligner_fn = retokenize.get_aligner_fn("openai-gpt") - token_aligners, tokens = zip(*(aligner_fn(sent) for sent in self.text)) - token_aligners, tokens = list(token_aligners), list(tokens) - token_index_tgt = [ - [token_aligner.project_tokens(idxs).tolist() for idxs in token_idxs] - for token_aligner, token_idxs in zip(token_aligners, self.token_index_src) - ] - span_index_tgt = [ - [token_aligner.project_span(start, end) for (start, end) in span_idxs] - for token_aligner, span_idxs in zip(token_aligners, self.span_index_src) - ] - assert self.tokens == tokens - assert self.token_index_tgt == token_index_tgt - assert self.span_index_tgt == span_index_tgt - - def test_sentencepiece(self): - self.tokens = [ - ["▁Members", "▁of", "▁the", "▁House", "▁clapped", "▁their", "▁hands"], - [ - "▁I", - "▁look", - "▁at", - "▁Sarah", - "'", - "s", - "▁dog", - ".", - "▁It", - "▁was", - "▁cute", - ".", - "!", - ], - [ - "▁Mr", - ".", - "▁I", - "m", - "mel", - "t", - "▁chose", - "▁to", - "▁focus", - "▁on", - "▁the", - "▁in", - "comp", - "re", - "hen", - "s", - "ibility", - "▁of", - "▁accounting", - "▁rules", - ".", - ], - ["▁What", "?"], - ] - self.token_index_tgt = [ - [[0], [1], [2], [3], [4], [5], [6]], - [[0], [1], [2], [3, 4, 5], [6, 7], [8], [9], [10, 11, 12]], - [ - [0, 1], - [2, 3, 4, 5], - [6], - [7], - [8], - [9], - [10], - [11, 12, 13, 14, 15, 16], - [17], - [18], - [19, 20], - ], - [[0, 1]], - ] - self.span_index_tgt = [ - [(0, 4), (5, 7)], - [(0, 1), (3, 8)], - [(0, 6), (10, 21), (10, 17), (11, 21)], - [(0, 2)], - ] - - aligner_fn = retokenize.get_aligner_fn("xlnet-base-cased") - token_aligners, tokens = zip(*(aligner_fn(sent) for sent in self.text)) - token_aligners, tokens = list(token_aligners), list(tokens) - token_index_tgt = [ - [token_aligner.project_tokens(idxs).tolist() for idxs in token_idxs] - for token_aligner, token_idxs in zip(token_aligners, self.token_index_src) - ] - span_index_tgt = [ - [token_aligner.project_span(start, end) for (start, end) in span_idxs] - for token_aligner, span_idxs in zip(token_aligners, self.span_index_src) - ] - assert self.tokens == tokens - assert self.token_index_tgt == token_index_tgt - assert self.span_index_tgt == span_index_tgt - - def test_bytebpe(self): - self.tokens = [ - ["Members", "Ġof", "Ġthe", "ĠHouse", "Ġcl", "apped", "Ġtheir", "Ġhands"], - ["I", "Ġlook", "Ġat", "ĠSarah", "'s", "Ġdog", ".", "ĠIt", "Ġwas", "Ġcute", ".", "!"], - [ - "Mr", - ".", - "ĠImm", - "elt", - "Ġchose", - "Ġto", - "Ġfocus", - "Ġon", - "Ġthe", - "Ġincomp", - "rehens", - "ibility", - "Ġof", - "Ġaccounting", - "Ġrules", - ".", - ], - ["What", "?"], - ] - self.token_index_tgt = [ - [[0], [1], [2], [3], [4, 5], [6], [7]], - [[0], [1], [2], [3, 4], [5, 6], [7], [8], [9, 10, 11]], - [[0, 1], [2, 3], [4], [5], [6], [7], [8], [9, 10, 11], [12], [13], [14, 15]], - [[0, 1]], - ] - self.span_index_tgt = [ - [(0, 4), (6, 8)], - [(0, 1), (3, 7)], - [(0, 4), (8, 16), (8, 12), (9, 16)], - [(0, 2)], - ] - - aligner_fn = retokenize.get_aligner_fn("roberta-base") - token_aligners, tokens = zip(*(aligner_fn(sent) for sent in self.text)) - token_aligners, tokens = list(token_aligners), list(tokens) - token_index_tgt = [ - [token_aligner.project_tokens(idxs).tolist() for idxs in token_idxs] - for token_aligner, token_idxs in zip(token_aligners, self.token_index_src) - ] - span_index_tgt = [ - [token_aligner.project_span(start, end) for (start, end) in span_idxs] - for token_aligner, span_idxs in zip(token_aligners, self.span_index_src) - ] - assert self.tokens == tokens - assert self.token_index_tgt == token_index_tgt - assert self.span_index_tgt == span_index_tgt diff --git a/tests/test_update_metrics.py b/tests/test_update_metrics.py deleted file mode 100644 index 2812b7e41..000000000 --- a/tests/test_update_metrics.py +++ /dev/null @@ -1,45 +0,0 @@ -import csv -import os -import shutil -import tempfile -import unittest -import jiant.tasks.tasks as tasks -import torch - - -class TestUpdateMetricsAccuracy(unittest.TestCase): - def setUp(self): - self.temp_dir = tempfile.mkdtemp() - self.path = os.path.join(self.temp_dir, "temp_dataset.tsv") - self.task = tasks.QQPTask("", 100, "qqp", tokenizer_name="MosesTokenizer") - # Note: predictions are of shape num_batches x batch_size x num_classes - # Here, QQP is binary thus num_classes = 2 and we make batch_size = 2. - predictions = torch.Tensor([[[1, 0], [1, 0]], [[1, 0], [0, 1]]]) - perfect_predictions = torch.Tensor([[[0, 1], [0, 1]], [[1, 0], [1, 0]]]) - true_labels = torch.Tensor([[1, 1], [0, 0]]) - - one_batch_predictions = torch.Tensor([[0], [1]]) - one_batch_true = torch.Tensor([[1], [0]]) - # thi will hav eto beoutsourced more. - out = {"logits": predictions, "labels": true_labels} - batch = {"tagmask": None} - self.task.update_metrics(out, batch) - self.imperfect_metrics = self.task.get_metrics(reset=True) - out = {"logits": perfect_predictions, "labels": true_labels} - self.task.update_metrics(out, batch) - self.perfect_metrics = self.task.get_metrics(reset=True) - - def test_accuracy(self): - # match predictions and labels to be the same format as in jiant/models.py - # only measures accuracy - assert "acc_f1" in list(self.imperfect_metrics.keys()) - assert self.imperfect_metrics["accuracy"] == 1.0 / 4.0 - assert self.perfect_metrics["accuracy"] == 1.0 - - def test_f1(self): - assert "f1" in self.imperfect_metrics - assert round(self.imperfect_metrics["f1"], 1) == 0.0 - assert round(self.perfect_metrics["f1"], 1) == 1.0 - - def tear_down(self): - shutil.rmtree(self.temp_dir) diff --git a/tests/test_utils.py b/tests/test_utils.py deleted file mode 100644 index d729ca99a..000000000 --- a/tests/test_utils.py +++ /dev/null @@ -1,156 +0,0 @@ -import csv -import os -import shutil -import tempfile -import unittest - -import jiant.utils.data_loaders as data_loaders - - -class TestLoadTsvLabelsOneSentence(unittest.TestCase): - def setUp(self): - self.temp_dir = tempfile.mkdtemp() - self.path = os.path.join(self.temp_dir, "temp_dataset.tsv") - with open(self.path, "w") as tsvfile: - writer = csv.writer(tsvfile, delimiter="\t") - writer.writerow(["sentence", "label"]) - writer.writerow(["it 's a charming and often affecting journey", 1]) - writer.writerow(["unflinchingly bleak and desperate", 0]) - - def test(self): - max_seq_len = 30 - sent1s, sent2s, labels = data_loaders.load_tsv( - "MosesTokenizer", - self.path, - max_seq_len, - s1_idx=0, - s2_idx=None, - label_idx=1, - skip_rows=1, - ) - print(sent2s) - assert sent2s == [] - assert ( - len(sent1s) == 2 - ), "The length of the set of first sentences != total rows in data file" - assert len(sent2s) == 0, "Second sentence does not exist yet len(sent2s) != 0" - assert len(labels) == 2, "The length of labels should be equal to rows in data file" - - def tearDown(self): - shutil.rmtree(self.temp_dir) - - -class TestLoadTsvLabelsTwoSentencesReturnIndices(unittest.TestCase): - def setUp(self): - self.temp_dir = tempfile.mkdtemp() - self.path = os.path.join(self.temp_dir, "temp_dataset_two_sentences.tsv") - with open(self.path, "w") as tsvfile: - writer = csv.writer(tsvfile, delimiter="\t") - writer.writerow(["sentence", "label"]) - writer.writerow( - ["it 's a charming and often affecting journey", "I agree what's better?", 1] - ) - writer.writerow(["unflinchingly bleak and desperate", "that's amazing", 0]) - - def test(self): - max_seq_len = 30 - sent1s, sent2s, labels, indices = data_loaders.load_tsv( - "MosesTokenizer", - self.path, - max_seq_len, - s1_idx=0, - s2_idx=1, - return_indices=1, - label_idx=1, - skip_rows=1, - ) - assert "charming" in sent1s[0], "sent1s is not tokenized first sentence" - assert "agree" in sent2s[0], "sent2s is not tokenized second sentence" - assert ( - len(sent1s) == 2 - ), "The length of the set of first sentences != total rows in data file" - assert ( - len(sent2s) == 2 - ), "The length of the set of second sentences != total rows in data file" - assert len(labels) == 2, "The length of labels should be equal to num rows in data file" - assert ( - len(indices) == 2 - ), "The length of returned indices should be equal to num rows in data file" - - def tearDown(self): - shutil.rmtree(self.temp_dir) - - -class TestLoadDiagnosticDataset(unittest.TestCase): - def setUp(self): - self.temp_dir = tempfile.mkdtemp() - self.path = os.path.join(self.temp_dir, "temp_dataset_diagnostic.tsv") - with open(self.path, "w") as tsvfile: - writer = csv.writer(tsvfile, delimiter="\t") - writer.writerow( - [ - "Lexical Semantics", - "Predicate-Argument Structure", - "Logic", - "Knowledge", - "Domain", - "Premise", - "Hypothesis", - "Label", - ] - ) - writer.writerow( - [ - "", - "", - "Negation", - "", - "Artificial", - "The cat sat on the mat", - "The cat did not sit on the mat.", - "contradiction", - ] - ) - - def test(self): - max_seq_len = 30 - label_map = {"contradiction": 0, "entailment": 1} - - def label_fn(x): - return label_map[x] - - output_dictionary = data_loaders.load_diagnostic_tsv( - "MosesTokenizer", - self.path, - max_seq_len, - s1_col="Premise", - s2_col="Hypothesis", - label_col="Label", - label_fn=label_fn, - ) - assert ( - len(output_dictionary["sents1"]) == 1 - ), "The length of the set of first sentences != total rows in data file" - assert ( - len(output_dictionary["sents2"]) == 1 - ), "Second sentence does not exist yet len(sent2s) != 0" - assert ( - len(output_dictionary["targs"]) == 1 - ), "The length of labels should be equal to rows in data file" - assert ( - len(output_dictionary["idxs"]) == 1 - ), "The length of labels should be equal to rows in data file" - assert ( - len(output_dictionary["knowledge"]) == 1 - ), "The length of labels should be equal to rows in data file" - assert ( - len(output_dictionary["lex_sem"][0]) == 0 - ), "If the field in row is blank in diagnostic dataset, we should return []" - assert output_dictionary["logic"][0] == [ - 0 - ], "If the field in row is not blank, we should return [0], where 0 is index" - assert "cat" in output_dictionary["sents1"][0], "sent1s output is wrong" - assert "not" in output_dictionary["sents2"][0] - - def tearDown(self): - shutil.rmtree(self.temp_dir) diff --git a/tests/test_utils_tokenizers.py b/tests/test_utils_tokenizers.py deleted file mode 100644 index 1074086e3..000000000 --- a/tests/test_utils_tokenizers.py +++ /dev/null @@ -1,259 +0,0 @@ -from jiant.utils.tokenizers import get_tokenizer, bert_get_tokenized_string_span_map, MosesTokenizer - - -def test_bert_get_tokenized_string_span_map1(): - text = "What does أنۢبياء anbiyā' mean in English?" - b_tokenizer = get_tokenizer("bert-large-cased") - result = bert_get_tokenized_string_span_map(text, b_tokenizer.tokenize(text)) - assert tuple(result) == ( - ("What", 0, 5), - ("does", 5, 9), - ("[UNK]", 9, 18), - ("an", 18, 20), - ("##bi", 20, 22), - ("##y", 22, 23), - ("##ā", 23, 24), - ("'", 24, 26), - ("mean", 26, 31), - ("in", 31, 34), - ("English", 34, 41), - ("?", 41, 42), - ) - - -def test_bert_get_tokenized_string_span_map2(): - text = "What does أنۢبياء أنۢبياء anbiyā' mean in English?" - b_tokenizer = get_tokenizer("bert-large-cased") - result = bert_get_tokenized_string_span_map(text, b_tokenizer.tokenize(text)) - assert tuple(result) == ( - ("What", 0, 5), - ("does", 5, 9), - ("[UNK]", 9, 26), - ("[UNK]", 26, 26), - ("an", 26, 28), - ("##bi", 28, 30), - ("##y", 30, 31), - ("##ā", 31, 32), - ("'", 32, 34), - ("mean", 34, 39), - ("in", 39, 42), - ("English", 42, 49), - ("?", 49, 50), - ) - - -def test_moses_ptb_detokenize(): - # Some of the detokenizations aren't perfect (usually dealing with non-English words, or - # problematic punctuation. This suite of text sentences just serves as a check against - # changes/improvements, to ensure that we get expected behavior. - test_cases = [ - [ - "For example , the marine archaean Cenarchaeum symbiosum lives within -LRB- is an endosymbiont of -RRB- the sponge Axinella mexicana .", - "For example, the marine archaean Cenarchaeum symbiosum lives within (is an endosymbiont of) the sponge Axinella mexicana.", - ], - [ - "Investigators are focusing on the ATR 72-600 's engines .", - "Investigators are focusing on the ATR 72-600's engines.", - ], - [ - "In the Netherlands , a low-lying country , dams were often applied to block rivers in order to regulate the water level and to prevent the sea from entering the marsh lands .", - "In the Netherlands, a low-lying country, dams were often applied to block rivers in order to regulate the water level and to prevent the sea from entering the marsh lands.", - ], - [ - "Although wildcats are solitary , the social behavior of domestic cats is much more variable and ranges from widely dispersed individuals to feral cat colonies that form around a food source , based on groups of co-operating females .", - "Although wildcats are solitary, the social behavior of domestic cats is much more variable and ranges from widely dispersed individuals to feral cat colonies that form around a food source, based on groups of co-operating females.", - ], - [ - "This in turn can be made into a nisbah adjective ishtir\u0101k\u012b ` socialist ' , from which an abstract noun ishtir\u0101kiyyah ` socialism ' can be derived .", - "This in turn can be made into a nisbah adjective ishtir\u0101k\u012b `socialist ', from which an abstract noun ishtir\u0101kiyyah` socialism' can be derived.", - ], - [ - "For example , if one car traveling east at 60 km/h passes another car traveling east at 50 km/h , then from the perspective of the slower car , the faster car is traveling east at 60 \u2212 50 = 10 km/h .", - "For example, if one car traveling east at 60 km/h passes another car traveling east at 50 km/h, then from the perspective of the slower car, the faster car is traveling east at 60 \u2212 50 = 10 km/h.", - ], - [ - "In an interview to be aired on Sky News today , he said the housing market is the `` biggest risk '' to the economy and has `` deep , deep structural problems '' .", - 'In an interview to be aired on Sky News today, he said the housing market is the "biggest risk" to the economy and has "deep, deep structural problems".', - ], - [ - "The letters were sent to ministers of the previous Labour government in the years of 2004 and 2005 and contain advocacy that has been described as `` particularly frank '' .", - 'The letters were sent to ministers of the previous Labour government in the years of 2004 and 2005 and contain advocacy that has been described as "particularly frank".', - ], - [ - "A `` bucky '' lamb is a lamb which was not castrated early enough , or which was castrated improperly -LRB- resulting in one testicle being retained -RRB- .", - 'A "bucky" lamb is a lamb which was not castrated early enough, or which was castrated improperly (resulting in one testicle being retained).', - ], - [ - "A significant hurdle in this research is proving that a subject 's conscious mind has not grasped a certain stimulus , due to the unreliability of self-reporting .", - "A significant hurdle in this research is proving that a subject's conscious mind has not grasped a certain stimulus, due to the unreliability of self-reporting.", - ], - [ - "I had the impression he was a serious and conscientious person '' .", - 'I had the impression he was a serious and conscientious person ".', - ], - [ - "In his inaugural address , Kennedy made the ambitious pledge to `` pay any price , bear any burden , meet any hardship , support any friend , oppose any foe , in order to assure the survival and success of liberty . ''", - 'In his inaugural address, Kennedy made the ambitious pledge to "pay any price, bear any burden, meet any hardship, support any friend, oppose any foe, in order to assure the survival and success of liberty."', - ], - [ - "The first nominee of the Party was John Hospers , who died last year , and he was a supporter of Republican President George W. Bush .", - "The first nominee of the Party was John Hospers, who died last year, and he was a supporter of Republican President George W. Bush.", - ], - [ - "In his view , transactions in a market economy are voluntary , and that the wide diversity that voluntary activity permits is a fundamental threat to repressive political leaders and greatly diminish their power to coerce .", - "In his view, transactions in a market economy are voluntary, and that the wide diversity that voluntary activity permits is a fundamental threat to repressive political leaders and greatly diminish their power to coerce.", - ], - [ - "Resistance organizations in the Gaza Strip continued to launch rockets aimed at the Tel Aviv area and other areas of Israel ; some of these rockets were intercepted by Israel 's Iron Dome system .", - "Resistance organizations in the Gaza Strip continued to launch rockets aimed at the Tel Aviv area and other areas of Israel; some of these rockets were intercepted by Israel's Iron Dome system.", - ], - [ - "Baruch ben Neriah , Jeremiah 's scribe , used this alphabet to create the later scripts of the Old Testament .", - "Baruch ben Neriah, Jeremiah's scribe, used this alphabet to create the later scripts of the Old Testament.", - ], - [ - "To digest vitamin B12 non-destructively , haptocorrin in saliva strongly binds and protects the B12 molecules from stomach acid as they enter the stomach and are cleaved from their protein complexes .", - "To digest vitamin B12 non-destructively, haptocorrin in saliva strongly binds and protects the B12 molecules from stomach acid as they enter the stomach and are cleaved from their protein complexes.", - ], - [ - "We 're a lot stronger than we ever have been , I think , mentally .", - "We're a lot stronger than we ever have been, I think, mentally.", - ], - [ - "Opponents consider governments as agents of neo-colonialism that are subservient to multinational corporations .", - "Opponents consider governments as agents of neo-colonialism that are subservient to multinational corporations.", - ], - [ - "In nouns , inflection for case is required in the singular for strong masculine and neuter nouns , in the genitive and sometimes in the dative .", - "In nouns, inflection for case is required in the singular for strong masculine and neuter nouns, in the genitive and sometimes in the dative.", - ], - [ - "DA Rosen 's November 7 presentation claimed honoring ICE holds would `` produce an undetermined amount of cost savings by reducing probation costs '' , as individuals otherwise on probation would be transferred to federal detention .", - 'DA Rosen\'s November 7 presentation claimed honoring ICE holds would "produce an undetermined amount of cost savings by reducing probation costs", as individuals otherwise on probation would be transferred to federal detention.', - ], - [ - "Canberra 's response came from Norwood , who drew a foul and scored a point from a free throw .", - "Canberra's response came from Norwood, who drew a foul and scored a point from a free throw.", - ], - [ - "He displayed an interest in literature from a young age , and began reading Greek and Roman myths and the fables of the Grimm brothers which `` instilled in him a lifelong affinity with Europe '' .", - 'He displayed an interest in literature from a young age, and began reading Greek and Roman myths and the fables of the Grimm brothers which "instilled in him a lifelong affinity with Europe".', - ], - [ - "In the history of India-Pakistan bilateral relations , the leader of one country has not visited the swearing-in ceremony of a leader of the other since 1947 , when the two countries became independent .", - "In the history of India-Pakistan bilateral relations, the leader of one country has not visited the swearing-in ceremony of a leader of the other since 1947, when the two countries became independent.", - ], - [ - "On Wednesday open-access journal ZooKeys published their paper on two of the new species , Sturnira bakeri and Sturnira burtonlimi .", - "On Wednesday open-access journal ZooKeys published their paper on two of the new species, Sturnira bakeri and Sturnira burtonlimi.", - ], - [ - "These groups often argue for the recognition of obesity as a disability under the US Americans With Disabilities Act -LRB- ADA -RRB- .", - "These groups often argue for the recognition of obesity as a disability under the US Americans With Disabilities Act (ADA).", - ], - [ - "An art car , featuring what might be the largest collection of singing robotic lobsters anywhere in the world was on display , curiously titled the `` Sashimi Tabernacle Choir . ''", - 'An art car, featuring what might be the largest collection of singing robotic lobsters anywhere in the world was on display, curiously titled the "Sashimi Tabernacle Choir."', - ], - [ - "As with many of Rio de Janeiro 's cultural monuments , the library was originally off-limits to the general public .", - "As with many of Rio de Janeiro's cultural monuments, the library was originally off-limits to the general public.", - ], - [ - "The initial condition and the final condition of the system are respectively described by values in a configuration space , for example a position space , or some equivalent space such as a momentum space .", - "The initial condition and the final condition of the system are respectively described by values in a configuration space, for example a position space, or some equivalent space such as a momentum space.", - ], - [ - "Weber began his studies of the subject in The Protestant Ethic and the Spirit of Capitalism , in which he argued that the redefinition of the connection between work and piety in Protestantism and especially in ascetic Protestant denominations , particularly Calvinism , shifted human effort towards rational efforts aimed at achieving economic gain .", - "Weber began his studies of the subject in The Protestant Ethic and the Spirit of Capitalism, in which he argued that the redefinition of the connection between work and piety in Protestantism and especially in ascetic Protestant denominations, particularly Calvinism, shifted human effort towards rational efforts aimed at achieving economic gain.", - ], - [ - "Under the assumption of perfect competition , supply is determined by marginal cost .", - "Under the assumption of perfect competition, supply is determined by marginal cost.", - ], - [ - "De Beauvoir 's adopted daughter and literary heir Sylvie Le Bon , unlike Elka\u00efm , published de Beauvoir 's unedited letters to both Sartre and Algren .", - "De Beauvoir's adopted daughter and literary heir Sylvie Le Bon, unlike Elka\u00efm, published de Beauvoir's unedited letters to both Sartre and Algren.", - ], - [ - "There were some residents in the damaged house who were not accounted for until about 4:30 p.m. when emergency personnel confirmed that three people inside the house were also killed .", - "There were some residents in the damaged house who were not accounted for until about 4:30 p.m. when emergency personnel confirmed that three people inside the house were also killed.", - ], - [ - "`` I think from the very beginning , one of the challenges we 've had with Iran is that they have looked at this administration and felt that the administration was not as strong as it needed to be .", - "\"I think from the very beginning, one of the challenges we've had with Iran is that they have looked at this administration and felt that the administration was not as strong as it needed to be.", - ], - [ - "Ricardo Men\u00e9ndez , vice president of the Productive Economic Area , said Venezuelan President Hugo Ch\u00e1vez has yearned for the creation of this project to empower Venezuelan construction .", - "Ricardo Men\u00e9ndez, vice president of the Productive Economic Area, said Venezuelan President Hugo Ch\u00e1vez has yearned for the creation of this project to empower Venezuelan construction.", - ], - [ - "In ancient Roman culture , Sunday was the day of the Sun god .", - "In ancient Roman culture, Sunday was the day of the Sun god.", - ], - [ - "According to him from his autobiography `` Tezkiret\u00fc ' l B\u00fcnyan '' , his masterpiece is the Selimiye Mosque in Edirne .", - 'According to him from his autobiography "Tezkiret\u00fc \'l B\u00fcnyan", his masterpiece is the Selimiye Mosque in Edirne.', - ], - [ - "These groups appear to have had a common origin with Viridiplantae and the three groups form the clade Archaeplastida , whose name implies that their chloroplasts were derived from a single ancient endosymbiotic event .", - "These groups appear to have had a common origin with Viridiplantae and the three groups form the clade Archaeplastida, whose name implies that their chloroplasts were derived from a single ancient endosymbiotic event.", - ], - [ - "Yesterday , the US 's Obama administration said it has ordered an investigation into the appropriateness of military hardware being sold to and deployed by police forces in the United States .", - "Yesterday, the US's Obama administration said it has ordered an investigation into the appropriateness of military hardware being sold to and deployed by police forces in the United States.", - ], - [ - "The five primary classifications can be further divided into secondary classifications such as rain forest , monsoon , tropical savanna , humid subtropical , humid continental , oceanic climate , Mediterranean climate , desert , steppe , subarctic climate , tundra , and polar ice cap .", - "The five primary classifications can be further divided into secondary classifications such as rain forest, monsoon, tropical savanna, humid subtropical, humid continental, oceanic climate, Mediterranean climate, desert, steppe, subarctic climate, tundra, and polar ice cap.", - ], - [ - "Some of the pictures and video coming out of the country do n't show blood and dismembered bodies , but instead show , according to witnesses , those who died from apparent suffocation ; some were foaming at the mouth and others were having convulsions .", - "Some of the pictures and video coming out of the country do n't show blood and dismembered bodies, but instead show, according to witnesses, those who died from apparent suffocation; some were foaming at the mouth and others were having convulsions.", - ], - [ - "Its glyphs were formed by pressing the end of a reed stylus into moist clay , not by tracing lines in the clay with the stylus as had been done previously .", - "Its glyphs were formed by pressing the end of a reed stylus into moist clay, not by tracing lines in the clay with the stylus as had been done previously.", - ], - [ - "In its modern form , the Greek language is the official language in two countries , Greece and Cyprus , a recognised minority language in seven other countries , and is one of the 24 official languages of the European Union .", - "In its modern form, the Greek language is the official language in two countries, Greece and Cyprus, a recognised minority language in seven other countries, and is one of the 24 official languages of the European Union.", - ], - [ - "For example , several writers in the early 1970s used the term to describe fax document transmission .", - "For example, several writers in the early 1970s used the term to describe fax document transmission.", - ], - [ - "Their lawyer Paul Castillo said today the couple `` knew that by coming forward they could help accelerate equality for all same-sex couples in Indiana by demonstrating the urgency of their need for equal dignity . ''", - 'Their lawyer Paul Castillo said today the couple "knew that by coming forward they could help accelerate equality for all same-sex couples in Indiana by demonstrating the urgency of their need for equal dignity."', - ], - [ - "For example , from the basic root sh-r-k ` share ' can be derived the Form VIII verb ishtaraka ` to cooperate , participate ' , and in turn its verbal noun ishtir\u0101k ` cooperation , participation ' can be formed .", - "For example, from the basic root sh-r-k `share 'can be derived the Form VIII verb ishtaraka` to cooperate, participate', and in turn its verbal noun ishtir\u0101k `cooperation, participation 'can be formed.", - ], - [ - "Russia Today goes on to say these laws are , `` intend -LSB- ed -RSB- to keep minors from being influenced by non-traditional sexual relationship propaganda and it will be enforced with fines , but not criminal punishment . ''", - 'Russia Today goes on to say these laws are, "intend [ed] to keep minors from being influenced by non-traditional sexual relationship propaganda and it will be enforced with fines, but not criminal punishment."', - ], - [ - "The language is spoken by at least 13 million people today in Greece , Cyprus , Italy , Albania , Turkey , and the Greek diaspora .", - "The language is spoken by at least 13 million people today in Greece, Cyprus, Italy, Albania, Turkey, and the Greek diaspora.", - ], - [ - "She spurred on attendees of the event to become more active in supporting women 's rights : `` It 's time for young women in this country to join the fight , because it 's our rights and our health that are at stake . ''", - "She spurred on attendees of the event to become more active in supporting women's rights: \"It's time for young women in this country to join the fight, because it's our rights and our health that are at stake.\"", - ], - [ - "Rajoy is to visit the site of the accident today .", - "Rajoy is to visit the site of the accident today.", - ], - [ - "From Southwest Asia domestic dairy animals spread to Europe -LRB- beginning around 7000 BC but not reaching Britain and Scandinavia until after 4000 BC -RRB- , and South Asia -LRB- 7000 -- 5500 BC -RRB- .", - "From Southwest Asia domestic dairy animals spread to Europe (beginning around 7000 BC but not reaching Britain and Scandinavia until after 4000 BC), and South Asia (7000 -- 5500 BC).", - ], - ] - moses_tokenizer = MosesTokenizer() - for sent, detok_sent_gold in test_cases: - tokens = sent.split() - detok_sent = moses_tokenizer.detokenize_ptb(tokens) - assert detok_sent == detok_sent_gold diff --git a/tests/test_winogender_metric.py b/tests/test_winogender_metric.py deleted file mode 100644 index bda22962d..000000000 --- a/tests/test_winogender_metric.py +++ /dev/null @@ -1,57 +0,0 @@ -import csv -import os -import shutil -from string import ascii_lowercase -import tempfile -import unittest -import pandas as pd - -from jiant.metrics.winogender_metrics import GenderParity - - -class TestWinogenderMetric(unittest.TestCase): - def setUp(self): - self.temp_dir = tempfile.mkdtemp() - self.batch_dict1 = [ - { - "sent1_str": "The employee called the customer to hand over the bag she stole", - "sent2_str": "The customer had stolen something.", - "preds": 0, - "pair_id": 5129, - }, - { - "sent1_str": "The employee called the customer to hand over the bag he stole", - "sent2_str": "The customer had stolen something.", - "preds": 0, - "pair_id": 5140, - }, - ] - self.batch_dict2 = [ - { - "sent1_str": "The employee called the customer to hand over the bag he stole", - "sent2_str": "The customer had stolen something.", - "preds": 1, - "pair_id": 5129, - }, - { - "sent2_str": "The employee called the customer to hand over the bag he stole", - "sent2_str": "The customer had stolen something.", - "preds": 0, - "pair_id": 5140, - }, - ] - - def test(self): - gender_parity_scorer = GenderParity() - gender_parity_scorer(self.batch_dict1) - acc = gender_parity_scorer.get_metric() - assert acc == 1.0 - gender_parity_scorer(self.batch_dict2) - acc = gender_parity_scorer.get_metric(reset=True) - assert acc == 0.5 - gender_parity_scorer(self.batch_dict2) - acc = gender_parity_scorer.get_metric(reset=True) - assert acc == 0.0 - - def tearDown(self): - shutil.rmtree(self.temp_dir) diff --git a/tests/test_write_preds.py b/tests/test_write_preds.py deleted file mode 100644 index 794349e24..000000000 --- a/tests/test_write_preds.py +++ /dev/null @@ -1,268 +0,0 @@ -import csv -import os -import os.path -import shutil -import tempfile -import unittest -from unittest import mock -import torch -import pandas as pd - -from jiant import evaluate -import jiant.tasks.tasks as tasks -from jiant.models import MultiTaskModel -from jiant.__main__ import evaluate_and_write - -from jiant.allennlp_mods.numeric_field import NumericField -from allennlp.data.token_indexers import SingleIdTokenIndexer -from allennlp.data import Instance, Token, vocabulary -from allennlp.data.fields import LabelField, ListField, MetadataField, TextField - - -def model_forward(task, batch, predict=True): - if task.name == "sts-b": - logits = torch.Tensor([0.6, 0.4]) - labels = torch.Tensor([0.875, 0.6]) - out = {"logits": logits, "labels": labels, "n_exs": 2, "preds": [1.0, 0.8]} - elif task.name == "wic": - logits = torch.Tensor([[0.5, 0.5], [0.5, 0.5], [0.5, 0.5], [0.5, 0.5]]) - labels = torch.LongTensor([0, 1, 1, 0]) - out = {"logits": logits, "labels": labels, "n_exs": 4, "preds": [0, 1, 1, 1]} - else: - raise ValueError("Unexpected task found") - - task.update_metrics(out, batch) - return out - - -class TestWritePreds(unittest.TestCase): - def sentence_to_text_field(self, sent, indexers): - """ Helper function to map a sequence of tokens into a sequence of - AllenNLP Tokens, then wrap in a TextField with the given indexers """ - return TextField(list(map(Token, sent)), token_indexers=indexers) - - def setUp(self): - """ - Since we're testing write_preds, we need to mock model predictions and the parts - of the model, arguments, and trainer needed to write to predictions. - Unlike in update_metrics tests, the actual contents of the examples in val_data - is not the most important as long as it adheres to the API necessary for examples - of that task. - """ - self.temp_dir = tempfile.mkdtemp() - self.path = os.path.join(self.temp_dir, "temp_dataset.tsv") - self.stsb = tasks.STSBTask(self.temp_dir, 100, "sts-b", tokenizer_name="MosesTokenizer") - self.wic = tasks.WiCTask(self.temp_dir, 100, "wic", tokenizer_name="MosesTokenizer") - stsb_val_preds = pd.DataFrame( - data=[ - { - "idx": 0, - "labels": 1.00, - "preds": 1.00, - "sent1_str": "A man with a hard hat is dancing.", - "sent2_str": "A man wearing a hard hat is dancing", - }, - { - "idx": 1, - "labels": 0.950, - "preds": 0.34, - "sent1_str": "A young child is riding a horse.", - "sent2_str": "A child is riding a horse.", - }, - ] - ) - wic_val_preds = pd.DataFrame( - data=[ - { - "idx": 0, - "sent1": "Room and board. ", - "sent2": "He nailed boards across the windows.", - "labels": 0, - "preds": 0, - }, - { - "idx": 1, - "sent1": "Hook a fish", - "sent2": "He hooked a snake accidentally.", - "labels": 1, - "preds": 1, - }, - ] - ) - indexers = {"bert_cased": SingleIdTokenIndexer("bert-xe-cased")} - self.wic.set_instance_iterable( - "val", - [ - Instance( - { - "sent1_str": MetadataField("Room and board."), - "sent2_str": MetadataField("He nailed boards"), - "idx": LabelField(0, skip_indexing=True), - "idx2": NumericField(2), - "idx1": NumericField(3), - "inputs": self.sentence_to_text_field( - [ - "[CLS]", - "Room", - "and", - "Board", - ".", - "[SEP]", - "He", - "nailed", - "boards", - "[SEP]", - ], - indexers, - ), - "labels": LabelField(0, skip_indexing=1), - } - ), - Instance( - { - "sent1_str": MetadataField("C ##ir ##culate a rumor ."), - "sent2_str": MetadataField("This letter is being circulated"), - "idx": LabelField(1, skip_indexing=True), - "idx2": NumericField(2), - "idx1": NumericField(3), - "inputs": self.sentence_to_text_field( - [ - "[CLS]", - "C", - "##ir", - "##culate", - "a", - "rumor", - "[SEP]", - "This", - "##let", - "##ter", - "is", - "being", - "c", - "##ir", - "##culated", - "[SEP]", - ], - indexers, - ), - "labels": LabelField(0, skip_indexing=1), - } - ), - Instance( - { - "sent1_str": MetadataField("Hook a fish'"), - "sent2_str": MetadataField("He hooked a snake accidentally"), - "idx": LabelField(2, skip_indexing=True), - "idx2": NumericField(2), - "idx1": NumericField(3), - "inputs": self.sentence_to_text_field( - [ - "[CLS]", - "Hook", - "a", - "fish", - "[SEP]", - "He", - "hooked", - "a", - "snake", - "accidentally", - "[SEP]", - ], - indexers, - ), - "labels": LabelField(1, skip_indexing=1), - } - ), - Instance( - { - "sent1_str": MetadataField("For recreation he wrote poetry."), - "sent2_str": MetadataField("Drug abuse is often regarded as recreation ."), - "idx": LabelField(3, skip_indexing=True), - "idx2": NumericField(2), - "idx1": NumericField(3), - "inputs": self.sentence_to_text_field( - [ - "[CLS]", - "For", - "re", - "##creation", - "he", - "wrote", - "poetry", - "[SEP]", - "Drug", - "abuse", - "is", - "often", - "re", - "##garded", - "as", - "re", - "##creation", - "[SEP]", - ], - indexers, - ), - "labels": LabelField(1, skip_indexing=1), - } - ), - ], - ) - self.val_preds = {"sts-b": stsb_val_preds, "wic": wic_val_preds} - self.vocab = vocabulary.Vocabulary.from_instances(self.wic.get_instance_iterable("val")) - self.vocab.add_token_to_namespace("True", "wic_tags") - for data in self.wic.get_instance_iterable("val"): - data.index_fields(self.vocab) - self.glue_tasks = [self.stsb, self.wic] - self.args = mock.Mock() - self.args.batch_size = 4 - self.args.cuda = -1 - self.args.run_dir = self.temp_dir - self.args.exp_dir = "" - - def test_write_preds_does_run(self): - evaluate.write_preds( - self.glue_tasks, self.val_preds, self.temp_dir, "test", strict_glue_format=True - ) - assert os.path.exists(self.temp_dir + "/STS-B.tsv") and os.path.exists( - self.temp_dir + "/WiC.jsonl" - ) - - def test_write_preds_glue(self): - evaluate.write_preds( - self.glue_tasks, self.val_preds, self.temp_dir, "test", strict_glue_format=True - ) - stsb_predictions = pd.read_csv(self.temp_dir + "/STS-B.tsv", sep="\t") - assert "index" in stsb_predictions.columns and "prediction" in stsb_predictions.columns - assert stsb_predictions.iloc[0]["prediction"] == 5.00 - assert stsb_predictions.iloc[1]["prediction"] == 1.7 - - def test_write_preds_superglue(self): - """ - Ensure that SuperGLUE write predictions for test is saved to the correct file - format. - """ - evaluate.write_preds( - [self.wic], self.val_preds, self.temp_dir, "test", strict_glue_format=True - ) - wic_predictions = pd.read_json(self.temp_dir + "/WiC.jsonl", lines=True) - assert "idx" in wic_predictions.columns and "label" in wic_predictions.columns - assert wic_predictions.iloc[0]["label"] == "false" - assert wic_predictions.iloc[1]["label"] == "true" - - @mock.patch("jiant.models.MultiTaskModel.forward", side_effect=model_forward) - def test_evaluate_and_write_does_run(self, model_forward_function): - """ - Testing that evaluate_and_write runs without breaking. - """ - with mock.patch("jiant.models.MultiTaskModel") as MockModel: - MockModel.return_value.eval.return_value = None - MockModel.return_value.forward = model_forward - MockModel.use_bert = 1 - model = MockModel() - evaluate_and_write(self.args, model, [self.wic], splits_to_write="val", cuda_device=-1) - - def tear_down(self): - shutil.rmtree(self.temp_dir) diff --git a/tests/test_zconf/__init__.py b/tests/test_zconf/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/test_zconf/jsons/empty.json b/tests/test_zconf/jsons/empty.json new file mode 100644 index 000000000..9e26dfeeb --- /dev/null +++ b/tests/test_zconf/jsons/empty.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/tests/test_zconf/jsons/simple.json b/tests/test_zconf/jsons/simple.json new file mode 100644 index 000000000..2840e4516 --- /dev/null +++ b/tests/test_zconf/jsons/simple.json @@ -0,0 +1,4 @@ +{ + "str_attr": "hello", + "int_default_attr": 3 +} \ No newline at end of file diff --git a/tests/test_zconf/jsons/store_true.json b/tests/test_zconf/jsons/store_true.json new file mode 100644 index 000000000..294ec2ecf --- /dev/null +++ b/tests/test_zconf/jsons/store_true.json @@ -0,0 +1,3 @@ +{ + "store_true_attr": true +} \ No newline at end of file diff --git a/tests/test_zconf/jsons/store_true_false.json b/tests/test_zconf/jsons/store_true_false.json new file mode 100644 index 000000000..c5f4d0804 --- /dev/null +++ b/tests/test_zconf/jsons/store_true_false.json @@ -0,0 +1,3 @@ +{ + "store_true_attr": false +} \ No newline at end of file diff --git a/tests/test_zconf/test_conf_jsons.py b/tests/test_zconf/test_conf_jsons.py new file mode 100644 index 000000000..470d3f010 --- /dev/null +++ b/tests/test_zconf/test_conf_jsons.py @@ -0,0 +1,168 @@ +import os +import shlex +import pytest + +import jiant.utils.zconf as zconf + + +def get_json_path(file_name): + return os.path.join(os.path.dirname(os.path.abspath(__file__)), "jsons", file_name) + + +@zconf.run_config +class RunConfiguration(zconf.RunConfig): + str_attr = zconf.attr() + int_attr = zconf.attr(type=int) + int_default_attr = zconf.attr(type=int, default=2) + store_true_attr = zconf.attr(action="store_true") + + +def test_args_required_command_line(): + with pytest.raises(SystemExit): + RunConfiguration.run_cli_json_prepend(cl_args=shlex.split("")) + + +def test_empty(): + args = RunConfiguration.run_cli_json_prepend( + cl_args=shlex.split( + f""" + --ZZsrc={get_json_path("empty.json")} + --str_attr "hi" + --int_attr 1 + """ + ) + ) + assert args.str_attr == "hi" + assert args.int_attr == 1 + assert args.int_default_attr == 2 + assert not args.store_true_attr + + +def test_simple(): + args = RunConfiguration.run_cli_json_prepend( + cl_args=shlex.split( + f""" + --ZZsrc={get_json_path("simple.json")} + --int_attr 1 + """ + ) + ) + assert args.str_attr == "hello" + assert args.int_attr == 1 + assert args.int_default_attr == 3 + assert not args.store_true_attr + + +def test_simple_override_conflict(): + with pytest.raises(RuntimeError): + RunConfiguration.run_cli_json_prepend( + cl_args=shlex.split( + f""" + --ZZsrc={get_json_path("simple.json")} + --str_attr "bye" + --int_attr 1 + """ + ) + ) + + +def test_simple_override_working(): + args = RunConfiguration.run_cli_json_prepend( + cl_args=shlex.split( + f""" + --ZZsrc={get_json_path("simple.json")} + --ZZoverrides str_attr + --str_attr "bye" + --int_attr 1 + """ + ) + ) + assert args.str_attr == "bye" + assert args.int_attr == 1 + assert args.int_default_attr == 3 + assert not args.store_true_attr + + +def test_simple_double_override(): + args = RunConfiguration.run_cli_json_prepend( + cl_args=shlex.split( + f""" + --ZZsrc={get_json_path("simple.json")} + --ZZoverrides str_attr int_default_attr + --str_attr "bye" + --int_attr 1 + --int_default_attr 4 + """ + ) + ) + assert args.str_attr == "bye" + assert args.int_attr == 1 + assert args.int_default_attr == 4 + assert not args.store_true_attr + + +def test_store_true(): + args = RunConfiguration.run_cli_json_prepend( + cl_args=shlex.split( + f""" + --ZZsrc={get_json_path("store_true.json")} + --str_attr "hello" + --int_attr 1 + """ + ) + ) + assert args.str_attr == "hello" + assert args.int_attr == 1 + assert args.int_default_attr == 2 + assert args.store_true_attr + + +def test_store_true_false(): + args = RunConfiguration.run_cli_json_prepend( + cl_args=shlex.split( + f""" + --ZZsrc={get_json_path("store_true_false.json")} + --str_attr "hello" + --int_attr 1 + """ + ) + ) + assert args.str_attr == "hello" + assert args.int_attr == 1 + assert args.int_default_attr == 2 + assert not args.store_true_attr + + +def test_store_true_override(): + args = RunConfiguration.run_cli_json_prepend( + cl_args=shlex.split( + f""" + --ZZsrc={get_json_path("store_true.json")} + --ZZoverrides store_true_attr + --str_attr "hello" + --int_attr 1 + """ + ) + ) + assert args.str_attr == "hello" + assert args.int_attr == 1 + assert args.int_default_attr == 2 + assert not args.store_true_attr + + +def test_store_true_false_override(): + args = RunConfiguration.run_cli_json_prepend( + cl_args=shlex.split( + f""" + --ZZsrc={get_json_path("store_true_false.json")} + --ZZoverrides store_true_attr + --str_attr "hello" + --int_attr 1 + --store_true_attr + """ + ) + ) + assert args.str_attr == "hello" + assert args.int_attr == 1 + assert args.int_default_attr == 2 + assert args.store_true_attr diff --git a/tests/test_zconf/test_confs.py b/tests/test_zconf/test_confs.py new file mode 100644 index 000000000..5b4cef58c --- /dev/null +++ b/tests/test_zconf/test_confs.py @@ -0,0 +1,37 @@ +import pytest + +import jiant.utils.zconf as zconf + + +@zconf.run_config +class Config(zconf.RunConfig): + attr1 = zconf.attr(default=None) + attr2 = zconf.attr(required=True) + + +def test_args(): + config = Config(attr1=1, attr2=2) + assert config.attr1 == 1 + assert config.attr2 == 2 + + config = Config(attr2=2) + assert config.attr1 is None + assert config.attr2 == 2 + + +def test_args_required(): + with pytest.raises(TypeError): + Config() + + +def test_args_required_command_line(): + with pytest.raises(SystemExit): + Config.run_cli_json_prepend(cl_args=[]) + + +def test_to_dict(): + config = Config(attr1=1, attr2=2) + conf_dict = config.to_dict() + assert len(conf_dict) == 2 + assert conf_dict["attr1"] == 1 + assert conf_dict["attr2"] == 2 diff --git a/tests/utils/__init__.py b/tests/utils/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/utils/config/base_config.json b/tests/utils/config/base_config.json new file mode 100644 index 000000000..f7cbdab80 --- /dev/null +++ b/tests/utils/config/base_config.json @@ -0,0 +1,9 @@ +{ + "run_name": "BERT_BASE", + "model": "BERT", + "tasks": ["mrpc"], + "params": { + "lr": 0.0003, + "val_interval": 100 + } +} \ No newline at end of file diff --git a/tests/utils/config/final_config.json b/tests/utils/config/final_config.json new file mode 100644 index 000000000..cc89c83b0 --- /dev/null +++ b/tests/utils/config/final_config.json @@ -0,0 +1,9 @@ +{ + "run_name": "BERT_BASE", + "model": "BERT", + "tasks": ["sst", "mrpc"], + "params": { + "val_interval": 100 + }, + "add_on_setting": "added_last" +} \ No newline at end of file diff --git a/tests/utils/config/first_override_config.json b/tests/utils/config/first_override_config.json new file mode 100644 index 000000000..f8cc1cf69 --- /dev/null +++ b/tests/utils/config/first_override_config.json @@ -0,0 +1,8 @@ +{ + "run_name": "BERT_BASE", + "model": "BERT", + "tasks": ["sst", "mrpc"], + "params": { + "lr": null + } +} \ No newline at end of file diff --git a/tests/utils/config/second_override_config.json b/tests/utils/config/second_override_config.json new file mode 100644 index 000000000..36ee66df0 --- /dev/null +++ b/tests/utils/config/second_override_config.json @@ -0,0 +1,3 @@ +{ + "add_on_setting": "added_last" +} \ No newline at end of file diff --git a/tests/utils/python/__init__.py b/tests/utils/python/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/utils/python/test_checks.py b/tests/utils/python/test_checks.py new file mode 100644 index 000000000..951690b93 --- /dev/null +++ b/tests/utils/python/test_checks.py @@ -0,0 +1,8 @@ +import jiant.utils.python.checks as py_checks + + +def test_dict_equal(): + assert py_checks.dict_equal({1: 2}, {1: 2}) + assert not py_checks.dict_equal({1: 2}, {1: 3}) + assert not py_checks.dict_equal({1: 2}, {2: 2}) + assert not py_checks.dict_equal({1: 2}, {2: 2, 1: 1}) diff --git a/tests/utils/python/test_datastructures.py b/tests/utils/python/test_datastructures.py new file mode 100644 index 000000000..dae8ca8be --- /dev/null +++ b/tests/utils/python/test_datastructures.py @@ -0,0 +1,167 @@ +import json +import pytest +from dataclasses import dataclass + +import jiant.utils.python.datastructures as py_datastructures + + +def test_take_one(): + assert py_datastructures.take_one([9]) == 9 + assert py_datastructures.take_one((9,)) == 9 + assert py_datastructures.take_one({9}) == 9 + assert py_datastructures.take_one("9") == "9" + assert py_datastructures.take_one({9: 10}) == 9 + + with pytest.raises(IndexError): + py_datastructures.take_one([]) + with pytest.raises(IndexError): + py_datastructures.take_one([1, 2]) + with pytest.raises(IndexError): + py_datastructures.take_one("2342134") + + +def test_chain_idx(): + # dict + d = {1: {2: 3}} + ls = [1, [2], [None, [3]]] + assert py_datastructures.chain_idx(d[1], [2]) == 3 + assert py_datastructures.chain_idx(d, [1, 2]) == 3 + with pytest.raises(KeyError): + py_datastructures.chain_idx(d, [1, 3]) + with pytest.raises(KeyError): + py_datastructures.chain_idx(d, [3]) + + # list + assert py_datastructures.chain_idx(ls, [0]) == 1 + assert py_datastructures.chain_idx(ls, [1]) == [2] + assert py_datastructures.chain_idx(ls, [1, 0]) == 2 + assert py_datastructures.chain_idx(ls, [2, 0]) is None + assert py_datastructures.chain_idx(ls, [2, 1, 0]) == 3 + with pytest.raises(TypeError): + py_datastructures.chain_idx(ls, [0, 0, 0]) + with pytest.raises(IndexError): + py_datastructures.chain_idx(ls, [1, 1]) + + +def test_chain_idx_get(): + # dict + d = {1: {2: 3}} + ls = [1, [2], [None, [3]]] + assert py_datastructures.chain_idx_get(d[1], [2], default=1234) == 3 + assert py_datastructures.chain_idx_get(d, [1, 3], default=1234) == 1234 + + # list + assert py_datastructures.chain_idx_get(ls, [0], default=1234) == 1 + assert py_datastructures.chain_idx_get(ls, [0, 0], default=1234) == 1234 + assert py_datastructures.chain_idx_get(ls, [1, 1], default=1234) == 1234 + + +def test_combine_dicts_with_disjoint_key_sets(): + combined_dict = py_datastructures.combine_dicts([{"d1_k1": "d1_v1"}, {"d2_k1": "d2_v1"}]) + expected_dict = {"d1_k1": "d1_v1", "d2_k1": "d2_v1"} + combined_sorted: str = json.dumps(combined_dict, sort_keys=True) + expected_sorted: str = json.dumps(expected_dict, sort_keys=True) + assert combined_sorted == expected_sorted + + +def test_combine_dicts_with_overlapping_key_sets(): + with pytest.raises(RuntimeError): + py_datastructures.combine_dicts([{"k1": "v1"}, {"k1": "v1"}]) + + +def test_partition_list(): + assert py_datastructures.partition_list(list(range(10)), 5) == [ + [0, 1], + [2, 3], + [4, 5], + [6, 7], + [8, 9], + ] + assert py_datastructures.partition_list(list(range(10)), 3) == [ + [0, 1, 2, 3], + [4, 5, 6, 7], + [8, 9], + ] + assert py_datastructures.partition_list(list(range(10)), 1) == [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]] + + +def test_extended_dataclass_mixin(): + @dataclass + class MyClass(py_datastructures.ExtendedDataClassMixin): + int1: int + str1: str + + assert MyClass.get_fields() == ["int1", "str1"] + + +def test_check_keys(): + def create_dict_with_keys(keys): + return {k: None for k in keys} + + # equal + d1 = create_dict_with_keys([1, 2, 3]) + assert py_datastructures.check_keys(d1, [1, 2, 3]) + assert not py_datastructures.check_keys(d1, [1, 2, 3, 4]) + assert not py_datastructures.check_keys(d1, [1]) + assert not py_datastructures.check_keys(d1, []) + + # subset + d1 = create_dict_with_keys([1, 2, 3]) + assert py_datastructures.check_keys(d1, [1, 2, 3], mode="subset") + assert py_datastructures.check_keys(d1, [1, 2, 3, 4], mode="subset") + assert not py_datastructures.check_keys(d1, [1, 2, 4], mode="subset") + assert not py_datastructures.check_keys(d1, [1, 2], mode="subset") + + # superset + d1 = create_dict_with_keys([1, 2, 3]) + assert py_datastructures.check_keys(d1, [1, 2, 3], mode="superset") + assert not py_datastructures.check_keys(d1, [1, 2, 3, 4], mode="superset") + assert not py_datastructures.check_keys(d1, [1, 2, 4], mode="superset") + assert py_datastructures.check_keys(d1, [1, 2], mode="superset") + + # strict_subset + d1 = create_dict_with_keys([1, 2, 3]) + assert not py_datastructures.check_keys(d1, [1, 2, 3], mode="strict_subset") + assert py_datastructures.check_keys(d1, [1, 2, 3, 4], mode="strict_subset") + assert not py_datastructures.check_keys(d1, [1, 2, 4], mode="strict_subset") + assert not py_datastructures.check_keys(d1, [1, 2], mode="strict_subset") + + # strict_superset + d1 = create_dict_with_keys([1, 2, 3]) + assert not py_datastructures.check_keys(d1, [1, 2, 3], mode="strict_superset") + assert not py_datastructures.check_keys(d1, [1, 2, 3, 4], mode="strict_superset") + assert not py_datastructures.check_keys(d1, [1, 2, 4], mode="strict_superset") + assert py_datastructures.check_keys(d1, [1, 2], mode="strict_superset") + + with pytest.raises(AssertionError): + py_datastructures.check_keys(d1, [1, 1]) + + +def test_get_unique_list_in_order(): + assert py_datastructures.get_unique_list_in_order([[1, 2], [3], [4]]) == [1, 2, 3, 4] + assert py_datastructures.get_unique_list_in_order([[1, 2, 3], [3], [4]]) == [1, 2, 3, 4] + assert py_datastructures.get_unique_list_in_order([[1, 2, 3], [4], [3]]) == [1, 2, 3, 4] + + +def test_reorder_keys(): + dict1 = {"a": 1, "b": 1, "c": 1} + assert list(py_datastructures.reorder_keys(dict1, key_list=["a", "b", "c"]).keys()) == [ + "a", + "b", + "c", + ] + assert list(py_datastructures.reorder_keys(dict1, key_list=["c", "a", "b"]).keys()) == [ + "c", + "a", + "b", + ] + with pytest.raises(AssertionError): + py_datastructures.reorder_keys(dict1, key_list=["d", "b", "d"]) + + +def test_set_dict_keys(): + d = {"a": 1, "b": 2, "c": 3} + assert list(py_datastructures.set_dict_keys(d, ["a", "b", "c"])) == ["a", "b", "c"] + assert list(py_datastructures.set_dict_keys(d, ["a", "c", "b"])) == ["a", "c", "b"] + with pytest.raises(AssertionError): + py_datastructures.set_dict_keys(d, ["a", "b"]) diff --git a/tests/utils/python/test_filesystem.py b/tests/utils/python/test_filesystem.py new file mode 100644 index 000000000..7d9cc250f --- /dev/null +++ b/tests/utils/python/test_filesystem.py @@ -0,0 +1,14 @@ +import os + +import jiant.utils.python.filesystem as py_filesystem + + +def test_get_code_base_path(): + code_base_path = py_filesystem.get_code_base_path() + assert os.path.exists(code_base_path) + + +def test_get_code_asset_path(): + import jiant + + assert py_filesystem.get_code_asset_path(os.path.join("jiant", "__init__.py")) == jiant.__file__ diff --git a/tests/utils/python/test_functional.py b/tests/utils/python/test_functional.py new file mode 100644 index 000000000..27381663c --- /dev/null +++ b/tests/utils/python/test_functional.py @@ -0,0 +1,9 @@ +import pytest + +import jiant.utils.python.functional as py_functional + + +def test_indexer(): + assert py_functional.indexer(1)({1: 2}) == 2 + with pytest.raises(KeyError): + py_functional.indexer("1")({1: 2}) diff --git a/tests/utils/python/test_logic.py b/tests/utils/python/test_logic.py new file mode 100644 index 000000000..451ac6ead --- /dev/null +++ b/tests/utils/python/test_logic.py @@ -0,0 +1,6 @@ +import jiant.utils.python.logic as py_logic + + +def test_replace_none(): + assert py_logic.replace_none(1, default=2) == 1 + assert py_logic.replace_none(None, default=2) == 2 diff --git a/tests/utils/test_config_handlers.py b/tests/utils/test_config_handlers.py new file mode 100644 index 000000000..adc328bd5 --- /dev/null +++ b/tests/utils/test_config_handlers.py @@ -0,0 +1,62 @@ +# -*- coding: utf-8 -*- +import json +import os + +from jiant.utils import config_handlers + + +def test_json_merge_patch(): + """Tests that JSON Merge Patch works as expected (https://tools.ietf.org/html/rfc7396)""" + target = """ + { + "title": "Goodbye!", + "author" : { + "givenName" : "John", + "familyName" : "Doe" + }, + "tags":[ "example", "sample" ], + "content": "This will be unchanged" + } + """ + patch = """ + { + "title": "Hello!", + "phoneNumber": "+01-123-456-7890", + "author": { + "familyName": null + }, + "tags": [ "example" ] + } + """ + merged = config_handlers.json_merge_patch(target, patch) + expected = """ + { + "title": "Hello!", + "author" : { + "givenName" : "John" + }, + "tags": [ "example" ], + "content": "This will be unchanged", + "phoneNumber": "+01-123-456-7890" + } + """ + merged_sorted: str = json.dumps(json.loads(merged), sort_keys=True) + expected_sorted: str = json.dumps(json.loads(expected), sort_keys=True) + assert merged_sorted == expected_sorted + + +def test_merging_multiple_json_configs(): + with open(os.path.join(os.path.dirname(__file__), "config/base_config.json")) as f: + base_config = f.read() + with open(os.path.join(os.path.dirname(__file__), "./config/first_override_config.json")) as f: + override_config_1 = f.read() + with open(os.path.join(os.path.dirname(__file__), "./config/second_override_config.json")) as f: + override_config_2 = f.read() + merged_config = config_handlers.merge_jsons_in_order( + [base_config, override_config_1, override_config_2] + ) + with open(os.path.join(os.path.dirname(__file__), "./config/final_config.json")) as f: + expected_config = f.read() + sorted_merged_config = json.dumps(json.loads(merged_config), sort_keys=True) + sorted_expected_config = json.dumps(json.loads(expected_config), sort_keys=True) + assert sorted_merged_config == sorted_expected_config diff --git a/tests/utils/test_data_handlers.py b/tests/utils/test_data_handlers.py new file mode 100644 index 000000000..567032a78 --- /dev/null +++ b/tests/utils/test_data_handlers.py @@ -0,0 +1,11 @@ +# -*- coding: utf-8 -*- +import os + +from jiant.utils import data_handlers + + +def test_md5_checksum_matches_expected_checksum(): + expected_md5_checksum = "4d5e587120171bc1ba4d49e2aa862a12" # calc'd w/ http://onlinemd5.com/ + filepath = os.path.join(os.path.dirname(__file__), "config/base_config.json") + computed_md5_checksum = data_handlers.md5_checksum(filepath) + assert expected_md5_checksum == computed_md5_checksum diff --git a/tests/utils/test_path_parse.py b/tests/utils/test_path_parse.py new file mode 100644 index 000000000..5c9d5a852 --- /dev/null +++ b/tests/utils/test_path_parse.py @@ -0,0 +1,17 @@ +import jiant.utils.path_parse as path_parse + + +def test_tags_to_regex(): + assert path_parse.tags_to_regex( + "/path/to/experiments/{model}/{task}" + ) == '/path/to/experiments/(?P\\w+)/(?P\\w+)' + + assert path_parse.tags_to_regex( + "/path/to/experiments/{model}/{task}", + default_format="(\\w|_)+" + ) == '/path/to/experiments/(?P(\\w|_)+)/(?P(\\w|_)+)' + + assert path_parse.tags_to_regex( + "/path/to/experiments/{model}/{task}", + format_dict={"task": "(\\w|_)+"} + ) == '/path/to/experiments/(?P\\w+)/(?P(\\w|_)+)' diff --git a/tests/utils/test_token_alignment.py b/tests/utils/test_token_alignment.py new file mode 100644 index 000000000..48f4b8393 --- /dev/null +++ b/tests/utils/test_token_alignment.py @@ -0,0 +1,573 @@ +import numpy as np +import pytest + +from jiant.utils.retokenize import TokenAligner, token_to_char + + +def test_token_to_char(): + expected_m = np.array( + # T h i s i s a t e s t + [ + [1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], # This + [0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0], # is + [0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0], # a + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1], + ], # test + dtype=np.int32, + ) + m = token_to_char("This is a test") + assert (m == expected_m).all() + + +def test_token_to_char_no_spaces(): + expected_m = np.array( + # T h i s i s a t e s t + [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]], # Thisisatest + dtype=np.int32, + ) + m = token_to_char("Thisisatest") + assert (m == expected_m).all() + + +def test_token_to_char_empty_str(): + expected_m = np.array([[]], dtype=np.int32) + m = token_to_char("") + assert (m == expected_m).all() + + +def test_token_aligner_project_single_token_index(): + source_tokens = ["abc", "def", "ghi", "jkl"] + target_tokens = ["abc", "d", "ef", "ghi", "jkl"] + ta = TokenAligner(source_tokens, target_tokens) + m = ta.project_token_idxs(1) + m_expected = np.array([1, 2]) + assert (m == m_expected).all() + + +def test_token_aligner_project_multiple_token_indices(): + source_tokens = ["abc", "def", "ghi", "jkl"] + target_tokens = ["abc", "d", "ef", "ghi", "jkl"] + ta = TokenAligner(source_tokens, target_tokens) + m = ta.project_token_idxs([1, 3]) + m_expected = np.array([1, 2, 4]) + assert (m == m_expected).all() + + +def test_token_aligner_project_to_empty_target_token_sequence(): + source_tokens = ["abc", "def", "ghi", "jkl"] + target_tokens = [] + ta = TokenAligner(source_tokens, target_tokens) + m = ta.project_token_idxs([1, 3]) + m_expected = np.array([]) + assert (m == m_expected).all() + + +def test_token_aligner_project_to_mismatched_token_sequence(): + source_tokens = ["abc", "def", "ghi", "jkl"] + target_tokens = ["qrs", "tuv", "wxy", "z"] + ta = TokenAligner(source_tokens, target_tokens) + m = ta.project_token_idxs([1]) + m_expected = np.array([]) + assert (m == m_expected).all() + + +def test_token_aligner_project_token_span(): + source_tokens = ["abc", "def", "ghi", "jkl"] + target_tokens = ["abc", "d", "ef", "ghi", "jkl"] + ta = TokenAligner(source_tokens, target_tokens) + m = ta.project_token_span(1, 2) + m_expected = np.array([1, 3]) + assert (m == m_expected).all() + + +def test_token_aligner_project_token_span_last_token_range_is_end_exclusive(): + source_tokens = ["abc", "def", "ghi", "jkl"] + target_tokens = ["abc", "d", "ef", "ghi", "jkl"] + ta = TokenAligner(source_tokens, target_tokens) + m = ta.project_token_span(3, 4) + m_expected = np.array([4, 5]) + assert (m == m_expected).all() + + +def test_wpm_tok_idx_proj_1(): + src_tokens = ["Members", "of", "the", "House", "clapped", "their", "hands"] + tgt_tokens = ["Members", "of", "the", "House", "clapped", "their", "hands"] + tgt_token_index = [[0], [1], [2], [3], [4], [5], [6]] + ta = TokenAligner(src_tokens, tgt_tokens) + for src_token_idx in range(len(src_tokens)): + projected_tgt_tok_idx = ta.project_token_idxs(src_token_idx) + assert (tgt_token_index[src_token_idx] == projected_tgt_tok_idx).all() + + +def test_wpm_tok_idx_proj_2(): + src_tokens = ["I", "look", "at", "Sarah's", "dog.", "It", "was", "cute.!"] + tgt_tokens = ["I", "look", "at", "Sarah", "'", "s", "dog", ".", "It", "was", "cute", ".", "!"] + tgt_token_index = [[0], [1], [2], [3, 4, 5], [6, 7], [8], [9], [10, 11, 12]] + ta = TokenAligner(src_tokens, tgt_tokens) + for src_token_idx in range(len(src_tokens)): + projected_tgt_tok_idx = ta.project_token_idxs(src_token_idx) + assert (tgt_token_index[src_token_idx] == projected_tgt_tok_idx).all() + + +def test_wpm_tok_idx_proj_3(): + src_tokens = [ + "Mr.", + "Immelt", + "chose", + "to", + "focus", + "on", + "the", + "incomprehensibility", + "of", + "accounting", + "rules.", + ] + tgt_tokens = [ + "Mr", + ".", + "I", + "##mme", + "##lt", + "chose", + "to", + "focus", + "on", + "the", + "in", + "##com", + "##p", + "##re", + "##hen", + "##si", + "##bility", + "of", + "accounting", + "rules", + ".", + ] + tgt_token_index = [ + [0, 1], + [2, 3, 4], + [5], + [6], + [7], + [8], + [9], + [10, 11, 12, 13, 14, 15, 16], + [17], + [18], + [19, 20], + ] + ta = TokenAligner(src_tokens, tgt_tokens) + for src_token_idx in range(len(src_tokens)): + projected_tgt_tok_idx = ta.project_token_idxs(src_token_idx) + assert (tgt_token_index[src_token_idx] == projected_tgt_tok_idx).all() + + +def test_wpm_tok_idx_proj_4(): + src_tokens = ["What?"] + tgt_tokens = ["What", "?"] + tgt_token_index = [[0, 1]] + ta = TokenAligner(src_tokens, tgt_tokens) + for src_token_idx in range(len(src_tokens)): + projected_tgt_tok_idx = ta.project_token_idxs(src_token_idx) + assert (tgt_token_index[src_token_idx] == projected_tgt_tok_idx).all() + + +def test_moses_tok_idx_proj_1(): + src_tokens = ["Members", "of", "the", "House", "clapped", "their", "hands"] + tgt_tokens = ["Members", "of", "the", "House", "clapped", "their", "hands"] + tgt_token_index = [[0], [1], [2], [3], [4], [5], [6]] + ta = TokenAligner(src_tokens, tgt_tokens) + for src_token_idx in range(len(src_tokens)): + projected_tgt_tok_idx = ta.project_token_idxs(src_token_idx) + assert (tgt_token_index[src_token_idx] == projected_tgt_tok_idx).all() + + +def test_moses_tok_idx_proj_2(): + src_tokens = ["I", "look", "at", "Sarah's", "dog.", "It", "was", "cute.!"] + tgt_tokens = ["I", "look", "at", "Sarah", "'s", "dog", ".", "It", "was", "cute", ".", "!"] + tgt_token_index = [[0], [1], [2], [3, 4], [5, 6], [7], [8], [9, 10, 11]] + ta = TokenAligner(src_tokens, tgt_tokens) + for src_token_idx in range(len(src_tokens)): + projected_tgt_tok_idx = ta.project_token_idxs(src_token_idx) + assert (tgt_token_index[src_token_idx] == projected_tgt_tok_idx).all() + + +def test_moses_tok_idx_proj_3(): + src_tokens = [ + "Mr.", + "Immelt", + "chose", + "to", + "focus", + "on", + "the", + "incomprehensibility", + "of", + "accounting", + "rules.", + ] + tgt_tokens = [ + "Mr.", + "Immelt", + "chose", + "to", + "focus", + "on", + "the", + "incomprehensibility", + "of", + "accounting", + "rules", + ".", + ] + tgt_token_index = [[0], [1], [2], [3], [4], [5], [6], [7], [8], [9], [10, 11]] + ta = TokenAligner(src_tokens, tgt_tokens) + for src_token_idx in range(len(src_tokens)): + projected_tgt_tok_idx = ta.project_token_idxs(src_token_idx) + assert (tgt_token_index[src_token_idx] == projected_tgt_tok_idx).all() + + +def test_moses_tok_idx_proj_4(): + src_tokens = ["What?"] + tgt_tokens = ["What", "?"] + tgt_token_index = [[0, 1]] + ta = TokenAligner(src_tokens, tgt_tokens) + for src_token_idx in range(len(src_tokens)): + projected_tgt_tok_idx = ta.project_token_idxs(src_token_idx) + assert (tgt_token_index[src_token_idx] == projected_tgt_tok_idx).all() + + +def test_bpe_tok_idx_proj_1(): + src_tokens = ["Members", "of", "the", "House", "clapped", "their", "hands"] + tgt_tokens = [ + "members", + "of", + "the", + "house", + "clapped", + "their", + "hands", + ] + tgt_token_index = [[0], [1], [2], [3], [4], [5], [6]] + ta = TokenAligner(src_tokens, tgt_tokens) + for src_token_idx in range(len(src_tokens)): + projected_tgt_tok_idx = ta.project_token_idxs(src_token_idx) + assert (tgt_token_index[src_token_idx] == projected_tgt_tok_idx).all() + + +def test_bpe_tok_idx_proj_2(): + src_tokens = ["I", "look", "at", "Sarah's", "dog.", "It", "was", "cute.!"] + tgt_tokens = [ + "i", + "look", + "at", + "sarah", + "'s", + "dog", + ".", + "it", + "was", + "cute", + ".", + "!", + ] + tgt_token_index = [[0], [1], [2], [3, 4], [5, 6], [7], [8], [9, 10, 11]] + ta = TokenAligner(src_tokens, tgt_tokens) + for src_token_idx in range(len(src_tokens)): + projected_tgt_tok_idx = ta.project_token_idxs(src_token_idx) + assert (tgt_token_index[src_token_idx] == projected_tgt_tok_idx).all() + + +def test_bpe_tok_idx_proj_3(): + src_tokens = [ + "Mr.", + "Immelt", + "chose", + "to", + "focus", + "on", + "the", + "incomprehensibility", + "of", + "accounting", + "rules.", + ] + tgt_tokens = [ + "mr.", + "im", + "melt", + "chose", + "to", + "focus", + "on", + "the", + "in", + "comprehen", + "si", + "bility", + "of", + "accounting", + "rules", + ".", + ] + tgt_token_index = [[0], [1, 2], [3], [4], [5], [6], [7], [8, 9, 10, 11], [12], [13], [14, 15]] + ta = TokenAligner(src_tokens, tgt_tokens) + for src_token_idx in range(len(src_tokens)): + projected_tgt_tok_idx = ta.project_token_idxs(src_token_idx) + assert (tgt_token_index[src_token_idx] == projected_tgt_tok_idx).all() + + +def test_bpe_tok_idx_proj_4(): + src_tokens = ["What?"] + tgt_tokens = ["what", "?"] + tgt_token_index = [[0, 1]] + ta = TokenAligner(src_tokens, tgt_tokens) + for src_token_idx in range(len(src_tokens)): + projected_tgt_tok_idx = ta.project_token_idxs(src_token_idx) + assert (tgt_token_index[src_token_idx] == projected_tgt_tok_idx).all() + + +def test_sentencepiece_tok_idx_proj_1(): + src_tokens = ["Members", "of", "the", "House", "clapped", "their", "hands"] + tgt_tokens = ["▁Members", "▁of", "▁the", "▁House", "▁clapped", "▁their", "▁hands"] + tgt_token_index = [[0], [1], [2], [3], [4], [5], [6]] + ta = TokenAligner(src_tokens, tgt_tokens) + for src_token_idx in range(len(src_tokens)): + projected_tgt_tok_idx = ta.project_token_idxs(src_token_idx) + assert (tgt_token_index[src_token_idx] == projected_tgt_tok_idx).all() + + +def test_sentencepiece_tok_idx_proj_2(): + src_tokens = ["I", "look", "at", "Sarah's", "dog.", "It", "was", "cute.!"] + tgt_tokens = [ + "▁I", + "▁look", + "▁at", + "▁Sarah", + "'", + "s", + "▁dog", + ".", + "▁It", + "▁was", + "▁cute", + ".", + "!", + ] + tgt_token_index = [[0], [1], [2], [3, 4, 5], [6, 7], [8], [9], [10, 11, 12]] + ta = TokenAligner(src_tokens, tgt_tokens) + for src_token_idx in range(len(src_tokens)): + projected_tgt_tok_idx = ta.project_token_idxs(src_token_idx) + assert (tgt_token_index[src_token_idx] == projected_tgt_tok_idx).all() + + +def test_sentencepiece_tok_idx_proj_3(): + src_tokens = [ + "Mr.", + "Immelt", + "chose", + "to", + "focus", + "on", + "the", + "incomprehensibility", + "of", + "accounting", + "rules.", + ] + tgt_tokens = [ + "▁Mr", + ".", + "▁I", + "m", + "mel", + "t", + "▁chose", + "▁to", + "▁focus", + "▁on", + "▁the", + "▁in", + "comp", + "re", + "hen", + "s", + "ibility", + "▁of", + "▁accounting", + "▁rules", + ".", + ] + tgt_token_index = [ + [0, 1], + [2, 3, 4, 5], + [6], + [7], + [8], + [9], + [10], + [11, 12, 13, 14, 15, 16], + [17], + [18], + [19, 20], + ] + ta = TokenAligner(src_tokens, tgt_tokens) + for src_token_idx in range(len(src_tokens)): + projected_tgt_tok_idx = ta.project_token_idxs(src_token_idx) + assert (tgt_token_index[src_token_idx] == projected_tgt_tok_idx).all() + + +def test_sentencepiece_tok_idx_proj_4(): + src_tokens = ["What?"] + tgt_tokens = ["▁What", "?"] + tgt_token_index = [[0, 1]] + ta = TokenAligner(src_tokens, tgt_tokens) + for src_token_idx in range(len(src_tokens)): + projected_tgt_tok_idx = ta.project_token_idxs(src_token_idx) + assert (tgt_token_index[src_token_idx] == projected_tgt_tok_idx).all() + + +def test_bytebpe_tok_idx_proj_1(): + src_tokens = ["Members", "of", "the", "House", "clapped", "their", "hands"] + tgt_tokens = ["Members", "Ġof", "Ġthe", "ĠHouse", "Ġcl", "apped", "Ġtheir", "Ġhands"] + tgt_token_index = [[0], [1], [2], [3], [4, 5], [6], [7]] + ta = TokenAligner(src_tokens, tgt_tokens) + for src_token_idx in range(len(src_tokens)): + projected_tgt_tok_idx = ta.project_token_idxs(src_token_idx) + assert (tgt_token_index[src_token_idx] == projected_tgt_tok_idx).all() + + +def test_bytebpe_tok_idx_proj_2(): + src_tokens = ["I", "look", "at", "Sarah's", "dog.", "It", "was", "cute.!"] + tgt_tokens = [ + "I", + "Ġlook", + "Ġat", + "ĠSarah", + "'s", + "Ġdog", + ".", + "ĠIt", + "Ġwas", + "Ġcute", + ".", + "!", + ] + tgt_token_index = [[0], [1], [2], [3, 4], [5, 6], [7], [8], [9, 10, 11]] + ta = TokenAligner(src_tokens, tgt_tokens) + for src_token_idx in range(len(src_tokens)): + projected_tgt_tok_idx = ta.project_token_idxs(src_token_idx) + assert (tgt_token_index[src_token_idx] == projected_tgt_tok_idx).all() + + +def test_bytebpe_tok_idx_proj_3(): + src_tokens = [ + "Mr.", + "Immelt", + "chose", + "to", + "focus", + "on", + "the", + "incomprehensibility", + "of", + "accounting", + "rules.", + ] + tgt_tokens = [ + "Mr", + ".", + "ĠImm", + "elt", + "Ġchose", + "Ġto", + "Ġfocus", + "Ġon", + "Ġthe", + "Ġincomp", + "rehens", + "ibility", + "Ġof", + "Ġaccounting", + "Ġrules", + ".", + ] + tgt_token_index = [[0, 1], [2, 3], [4], [5], [6], [7], [8], [9, 10, 11], [12], [13], [14, 15]] + ta = TokenAligner(src_tokens, tgt_tokens) + for src_token_idx in range(len(src_tokens)): + projected_tgt_tok_idx = ta.project_token_idxs(src_token_idx) + assert (tgt_token_index[src_token_idx] == projected_tgt_tok_idx).all() + + +def test_bytebpe_tok_idx_proj_4(): + src_tokens = ["What?"] + tgt_tokens = ["What", "?"] + tgt_token_index = [[0, 1]] + ta = TokenAligner(src_tokens, tgt_tokens) + for src_token_idx in range(len(src_tokens)): + projected_tgt_tok_idx = ta.project_token_idxs(src_token_idx) + assert (tgt_token_index[src_token_idx] == projected_tgt_tok_idx).all() + + +""" +Note: test_project_token_span_* tests use same data and token aligner as test_bytebpe_tok_idx_proj_1. +Token projection is tested extensively above, the focus of the following tests is span projection. +For span prediction token token projection does the heavy lifting — tests covering span prediction +need to check that careful indexing. +""" + + +def test_project_token_span_single_token(): + src_tokens = ["Members", "of", "the", "House", "clapped", "their", "hands"] + tgt_tokens = ["Members", "Ġof", "Ġthe", "ĠHouse", "Ġcl", "apped", "Ġtheir", "Ġhands"] + # reference: tgt_token_index = [[0], [1], [2], [3], [4, 5], [6], [7]] + ta = TokenAligner(src_tokens, tgt_tokens) + assert (0, 1) == ta.project_token_span(0, 1) + + +def test_project_token_span_covering_multiple_source_sequence_tokens(): + src_tokens = ["Members", "of", "the", "House", "clapped", "their", "hands"] + tgt_tokens = ["Members", "Ġof", "Ġthe", "ĠHouse", "Ġcl", "apped", "Ġtheir", "Ġhands"] + # reference: tgt_token_index = [[0], [1], [2], [3], [4, 5], [6], [7]] + ta = TokenAligner(src_tokens, tgt_tokens) + assert (0, 2) == ta.project_token_span(0, 2) + + +def test_project_token_span_covering_multiple_target_sequence_tokens(): + src_tokens = ["Members", "of", "the", "House", "clapped", "their", "hands"] + tgt_tokens = ["Members", "Ġof", "Ġthe", "ĠHouse", "Ġcl", "apped", "Ġtheir", "Ġhands"] + # reference: tgt_token_index = [[0], [1], [2], [3], [4, 5], [6], [7]] + ta = TokenAligner(src_tokens, tgt_tokens) + assert (4, 6) == ta.project_token_span(4, 5) + + +def test_project_token_span_covering_whole_sequence(): + src_tokens = ["Members", "of", "the", "House", "clapped", "their", "hands"] + tgt_tokens = ["Members", "Ġof", "Ġthe", "ĠHouse", "Ġcl", "apped", "Ġtheir", "Ġhands"] + # reference: tgt_token_index = [[0], [1], [2], [3], [4, 5], [6], [7]] + ta = TokenAligner(src_tokens, tgt_tokens) + assert (0, 8) == ta.project_token_span(0, 7) + + +def test_project_invalid_span(): + src_tokens = ["Members", "of", "the", "House", "clapped", "their", "hands"] + tgt_tokens = ["Members", "Ġof", "Ġthe", "ĠHouse", "Ġcl", "apped", "Ġtheir", "Ġhands"] + # reference: tgt_token_index = [[0], [1], [2], [3], [4, 5], [6], [7]] + ta = TokenAligner(src_tokens, tgt_tokens) + with pytest.raises(ValueError): + ta.project_token_span(0, 0) + + +def test_private_project_token_span(): + mat = np.eye(5, dtype=int) + mat[0][0] = 0 + mat[3][3] = 0 + assert TokenAligner._project_span(mat, 1, 3, inclusive=True) == (1, 2) + assert TokenAligner._project_span(mat, 1, 3, inclusive=False) == (1, 3) + assert TokenAligner._project_span(mat, 1, 2, inclusive=True) == (1, 2) + assert TokenAligner._project_span(mat, 1, 2, inclusive=False) == (1, 2) + assert TokenAligner._project_span(mat, 1, 4, inclusive=True) == (1, 4) + assert TokenAligner._project_span(mat, 1, 4, inclusive=False) == (1, 3) diff --git a/tests/utils/test_tokenization_normalization.py b/tests/utils/test_tokenization_normalization.py new file mode 100644 index 000000000..c07ae44bf --- /dev/null +++ b/tests/utils/test_tokenization_normalization.py @@ -0,0 +1,281 @@ +import pytest + +import jiant.utils.tokenization_normalization as tn + +from transformers import BertTokenizer, XLMTokenizer, RobertaTokenizer, AlbertTokenizer + + +def test_process_wordpiece_token_sequence(): + expected_adjusted_wordpiece_tokens = [ + "Mr", + ".", + "I", + "mme", + "lt", + "chose", + "to", + "focus", + "on", + "the", + "in", + "com", + "p", + "re", + "hen", + "si", + "bility", + "of", + "accounting", + "rules", + ".", + ] + original_wordpiece_tokens = [ + "Mr", + ".", + "I", + "##mme", + "##lt", + "chose", + "to", + "focus", + "on", + "the", + "in", + "##com", + "##p", + "##re", + "##hen", + "##si", + "##bility", + "of", + "accounting", + "rules", + ".", + ] + adjusted_wordpiece_tokens = tn._process_wordpiece_tokens(original_wordpiece_tokens) + assert adjusted_wordpiece_tokens == expected_adjusted_wordpiece_tokens + + +def test_process_sentencepiece_token_sequence(): + expected_adjusted_sentencepiece_tokens = [ + "Mr", + ".", + "I", + "m", + "mel", + "t", + "chose", + "to", + "focus", + "on", + "the", + "in", + "comp", + "re", + "hen", + "s", + "ibility", + "of", + "accounting", + "rules", + ".", + ] + original_sentencepiece_tokens = [ + "▁Mr", + ".", + "▁I", + "m", + "mel", + "t", + "▁chose", + "▁to", + "▁focus", + "▁on", + "▁the", + "▁in", + "comp", + "re", + "hen", + "s", + "ibility", + "▁of", + "▁accounting", + "▁rules", + ".", + ] + adjusted_sentencepiece_tokens = tn._process_sentencepiece_tokens(original_sentencepiece_tokens) + assert adjusted_sentencepiece_tokens == expected_adjusted_sentencepiece_tokens + + +def test_process_bytebpe_token_sequence(): + expected_adjusted_bytebpe_tokens = [ + "Mr", + ".", + "Imm", + "elt", + "chose", + "to", + "focus", + "on", + "the", + "incomp", + "rehens", + "ibility", + "of", + "accounting", + "rules", + ".", + ] + original_bytebpe_tokens = [ + "Mr", + ".", + "ĠImm", + "elt", + "Ġchose", + "Ġto", + "Ġfocus", + "Ġon", + "Ġthe", + "Ġincomp", + "rehens", + "ibility", + "Ġof", + "Ġaccounting", + "Ġrules", + ".", + ] + adjusted_bytebpe_tokens = tn._process_bytebpe_tokens(original_bytebpe_tokens) + assert adjusted_bytebpe_tokens == expected_adjusted_bytebpe_tokens + + +""" +The following tests are marked slow because they load/download real Transformers tokenizers. +These tests will only be run with pytest flag --runslow. TODO: consider mocking tokenizers. +""" + + +@pytest.mark.slow +def test_space_tokenization_and_bert_uncased_tokenization_normalization(): + text = "Jeff Immelt chose to focus on the incomprehensibility of accounting rules ." + space_tokenized = text.split(" ") + tokenizer = BertTokenizer.from_pretrained("bert-base-uncased") + target_tokenized = tokenizer.tokenize(text) + normed_space_tokenized, normed_target_tokenized = tn.normalize_tokenizations( + space_tokenized, target_tokenized, tokenizer + ) + assert "".join(normed_space_tokenized) == "".join(normed_target_tokenized) + + +@pytest.mark.slow +def test_space_tokenization_and_bert_cased_tokenization_normalization(): + text = "Jeff Immelt chose to focus on the incomprehensibility of accounting rules ." + space_tokenized = text.split(" ") + tokenizer = BertTokenizer.from_pretrained("bert-base-cased") + target_tokenized = tokenizer.tokenize(text) + normed_space_tokenized, normed_target_tokenized = tn.normalize_tokenizations( + space_tokenized, target_tokenized, tokenizer + ) + assert "".join(normed_space_tokenized) == "".join(normed_target_tokenized) + + +@pytest.mark.slow +def test_space_tokenization_and_xlm_uncased_tokenization_normalization(): + text = "Jeff Immelt chose to focus on the incomprehensibility of accounting rules ." + space_tokenized = text.split(" ") + tokenizer = XLMTokenizer.from_pretrained("xlm-mlm-en-2048") + target_tokenized = tokenizer.tokenize(text) + normed_space_tokenized, normed_target_tokenized = tn.normalize_tokenizations( + space_tokenized, target_tokenized, tokenizer + ) + assert "".join(normed_space_tokenized) == "".join(normed_target_tokenized) + + +@pytest.mark.slow +def test_space_tokenization_and_roberta_tokenization_normalization(): + text = "Jeff Immelt chose to focus on the incomprehensibility of accounting rules ." + space_tokenized = text.split(" ") + tokenizer = RobertaTokenizer.from_pretrained("roberta-base") + target_tokenized = tokenizer.tokenize(text) + normed_space_tokenized, normed_target_tokenized = tn.normalize_tokenizations( + space_tokenized, target_tokenized, tokenizer + ) + assert "".join(normed_space_tokenized) == "".join(normed_target_tokenized) + + +@pytest.mark.slow +def test_space_tokenization_and_albert_tokenization_normalization(): + text = "Jeff Immelt chose to focus on the incomprehensibility of accounting rules ." + space_tokenized = text.split(" ") + tokenizer = AlbertTokenizer.from_pretrained("albert-base-v1") + target_tokenized = tokenizer.tokenize(text) + normed_space_tokenized, normed_target_tokenized = tn.normalize_tokenizations( + space_tokenized, target_tokenized, tokenizer + ) + assert "".join(normed_space_tokenized) == "".join(normed_target_tokenized) + + +@pytest.mark.slow +def test_normalize_empty_tokenizations(): + text = "" + space_tokenized = text.split(" ") + tokenizer = AlbertTokenizer.from_pretrained("albert-base-v1") + target_tokenized = tokenizer.tokenize(text) + with pytest.raises(ValueError): + tn.normalize_tokenizations(space_tokenized, target_tokenized, tokenizer) + + +@pytest.mark.slow +def test_space_tokenization_and_unusual_roberta_tokenization_normalization(): + text = ( + "As a practitioner of ethnic humor from the old days on the Borscht Belt , live " + "television and the nightclub circuit , Mr. Mason instinctively reached for the " + "vernacular ." + ) + space_tokenized = text.split(" ") + tokenizer = RobertaTokenizer.from_pretrained("roberta-base") + target_tokenized = tokenizer.tokenize(text) + # note 1: exposing the target tokenization to highlight an unusual tokenization: + # " vernacular" -> 'Ġ', 'vern', 'acular' (the usual pattern suggests 'Ġvern', 'acular') + assert target_tokenized == [ + "As", + "Ġa", + "Ġpractitioner", + "Ġof", + "Ġethnic", + "Ġhumor", + "Ġfrom", + "Ġthe", + "Ġold", + "Ġdays", + "Ġon", + "Ġthe", + "ĠB", + "ors", + "cht", + "ĠBelt", + "Ġ,", + "Ġlive", + "Ġtelevision", + "Ġand", + "Ġthe", + "Ġnightclub", + "Ġcircuit", + "Ġ,", + "ĠMr", + ".", + "ĠMason", + "Ġinstinctively", + "Ġreached", + "Ġfor", + "Ġthe", + "Ġ", + "vern", + "acular", + "Ġ.", + ] + normed_space_tokenized, normed_target_tokenized = tn.normalize_tokenizations( + space_tokenized, target_tokenized, tokenizer + ) + # note: 2: the assert below shows that even with the unusual tokenization (see note 1 above), + # after normalization the space tokenization and the target tokenization match. + assert "".join(normed_space_tokenized) == "".join(normed_target_tokenized) diff --git a/tests/utils/test_utils.py b/tests/utils/test_utils.py new file mode 100644 index 000000000..b88b40262 --- /dev/null +++ b/tests/utils/test_utils.py @@ -0,0 +1,37 @@ +from jiant.tasks.utils import truncate_sequences + + +def test_truncate_empty_sequence(): + seq = [] + trunc_seq = truncate_sequences(seq, 10) + assert not trunc_seq + + +def test_truncate_single_sequence_default_trunc_end(): + seq = [["abc", "def", "ghi", "jkl", "mno", "pqr", "stu", "vwx", "yz"]] + trunc_seq = truncate_sequences(seq, 8) + assert trunc_seq == [["abc", "def", "ghi", "jkl", "mno", "pqr", "stu", "vwx"]] + + +def test_truncate_single_sequence_trunc_start(): + seq = [["abc", "def", "ghi", "jkl", "mno", "pqr", "stu", "vwx", "yz"]] + trunc_seq = truncate_sequences(seq, 8, False) + assert trunc_seq == [["def", "ghi", "jkl", "mno", "pqr", "stu", "vwx", "yz"]] + + +def test_truncate_two_sequences_default_trunc_end(): + seqs = [["abc", "def", "ghi", "jkl"], ["mno", "pqr", "stu", "vwx", "yz"]] + trunc_seqs = truncate_sequences(seqs, 8) + assert trunc_seqs == [["abc", "def", "ghi", "jkl"], ["mno", "pqr", "stu", "vwx"]] + + +def test_truncate_more_than_two_sequences_trunc_start(): + seqs = [["abc", "def", "ghi"], ["jkl", "mno", "pqr"], ["stu", "vwx", "yz"]] + trunc_seqs = truncate_sequences(seqs, 8) + assert trunc_seqs == [["abc", "def"], ["jkl", "mno", "pqr"], ["stu", "vwx", "yz"]] + + +def test_truncate_two_sequences_default_trunc_start(): + seqs = [["abc", "def", "ghi", "jkl"], ["mno", "pqr", "stu", "vwx", "yz"]] + trunc_seqs = truncate_sequences(seqs, 8, False) + assert trunc_seqs == [["abc", "def", "ghi", "jkl"], ["pqr", "stu", "vwx", "yz"]] diff --git a/tutorials/adding_tasks.md b/tutorials/adding_tasks.md deleted file mode 100644 index d06f497c9..000000000 --- a/tutorials/adding_tasks.md +++ /dev/null @@ -1,181 +0,0 @@ -# How to Add a Task -Alright, so you want to try using `jiant` on a new task. -But where do you begin? - - -Let us make an imaginary pair classification task with a new dataset SomeDataset, which is made up of two sentences and a binary label, and we want to score based on F1 and use mean square error loss. - -First, we need to make sure that your files are in the right place. Let us say that it is under your data/SomeDataset folder. Make sure your file is in a TSV file. - -The first stop is [`jiant/tasks/tasks.py`. -](https://github.com/nyu-mll/jiant/blob/master/jiant/tasks/tasks.py) - -We keep track of tasks via a registry, so you'll have to add a decorator to the beginning of your task. In the rel_path, you don't have to add the full path, but only what comes after your general data_dir path. - -```python -@register_task("new-task-name", rel_path='SomeData') -``` -There are a lot of tasks already supported in jiant (see list [here](https://jiant.info/documentation#/?id=running)), so inherit from one of the task types (unless your task is its own type). Let's say ours is a type of PairClassificationTask, so we can add that the our task class definition. Here's a skeleton! - - -```sh -@register_task("new-task-name", rel_path='SomeData') -class SomeDataClassificationTask(PairClassificationTask): - def __init__(self, path, max_seq_len, name, **kw): - super().__init__(name, n_classes=2, **kw) - def load_data(self, path, max_seq_len): - '''Process the dataset located at data_file.''' - def _make_instance(input1, input2, label): - ''' Make Allennlp instances from records ''' - def update_metrics(self, out, batch): - '''Update metrics specific to the task''' - def get_metrics(self, reset=False): - '''Get metrics specific to the task''' -``` - - - -Let's walk through each of the major parts: - -A lot of the following functions may already be written for your task type (especially if you're using a supported task type like PairClassificationTask). All functions listed with inheritable are those that are written for supported task types. You still may want to override them in your task for task-specific processing though! - - - -1. The `load_data` (inheritable) function is for loading your data. This function loads your TSV/JSONL/... to a format that can be made into AllenNLP iterators. In this function, you will want to call `load_tsv` from `jiant/utils/data_loaders.py`, which loads and tokenizes the data. Currently, only English tokenization is supported. You can specify the fields to load from as parameters to `load_tsv` (which right now is based on number-based indexing). See [here](https://github.com/jsalt18-sentence-repl/jiant/blob/master/jiant/utils/data_loaders.py) for more documentation on `load_tsv`. An example is below - -```python - def load_data(self, path, max_seq_len): - tr_data = load_tsv(self._tokenizer_name, os.path.join(path, "train.tsv"), - max_seq_len, s1_idx=3, s2_idx=4, targ_idx=5, skip_rows=1) - val_data = load_tsv(self._tokenizer_name, os.path.join(path, "dev.tsv"), - max_seq_len, s1_idx=3, s2_idx=4, targ_idx=5, skip_rows=1) - te_data = load_tsv(self._tokenizer_name, os.path.join(path, 'test.tsv'), - max_seq_len, s1_idx=1, s2_idx=2, targ_idx=None, idx_idx=0, skip_rows=1) - self.train_data_text = tr_data - self.val_data_text = val_data - self.test_data_text = te_data - - ``` - -2. The `_make_instance` (inheritable) function, which is defined for PairClassificationTask but we may want to overwrite, indexes the data and converts our Python records into AllenNLP instances. -```python - def _make_instance(input1, input2, label): - ''' from multiple types in one column create multiple fields ''' - d = {} - d["input1"] = sentence_to_text_field(input1, indexers) - d["input2"] = sentence_to_text_field(input2, indexers) - d["labels"] = LabelField(label, label_namespace="labels", - skip_indexing=True) - d['sent1_str'] = MetadataField(" ".join(input1[1:-1])) - d['sent2_str'] = MetadataField(" ".join(input2[1:-1])) - return Instance(d) - ``` -3. `update_metrics` (inheritable) is a function to update scorers, which are configerable scorers (mostly from AllenNLP) such as F1Measure or BooleanAccuracy that keeps track of task-specific scores. Let us say that we want to only update F1 and ignore accuracy. In that case, you can set self.scorers = [self.f1_scorer]. You will have to implement `update_metrics` for your task, which can look something like this (if you're just updating F1). - -```python - def update_metrics(self, out, batch): - logits = out["logits"] - labels = batch["labels"] - for scorer in self.get_scorers(): - scorer(logits, labels) -``` -4. `get_metrics` (inheritable) is a function that returns the metrics from the updated scorers in dictionary form. Since we're only getting F1, we should set the get_metrics function to be: -```python - def get_metrics(self, reset=False): - '''Get metrics specific to the task''' - f1 = self.f1_scorer.get_metric(reset)[2] - return {'f1': f1} -``` -5. `get_sentences` (inheritable) iterates over all text to index and returns an iterator of AllenNLP instances of your train and validation sets. Often, you can just set self.sentences to be a list of sentences to handle this, since `get_sentences` yields self.sentences in the `Task` class. Below, after loading the data and saving it into self.train_data_text and self.val_data_text in `load_data`, we set the below: -```python -self.sentences = self.train_data_text[0] + self.val_data_text[0] -``` -6. `process_split` (inheritable) takes in a split of your data and produces an iterable of AllenNLP Instances. An Instance is a wrapper around a dictionary of (field_name, Field) pairs. Fields are objects to help with data processing (indexing, padding, etc.). This is handled for us here, since we inherit from `PairClassificationTask`, but if you're writing a task that inherits directly from `Task`, you should look to `PairClassificationTask` for an example of how to implement this method yourself. - -7. `count_examples` (inheritable) sets `task.example_counts` (Dict[str:int]): the number of examples per split (train, val, test). - -8. `val_metric` (inheritable) is a string variable that is the name of task-specific metric to track during training, e.g. F1 score. - -9. `val_metric_decreases` (inheritable) is a boolean for whether or not the objective function should be minimized or maximized. The default is set to False. - - -Your finished task class may look something like this: - - -```python -@register_task("new-task-name", rel_path='SomeData') -class SomeDataClassificationTask(PairClassificationTask): - def __init__(self, path, max_seq_len, name, **kw): - super().__init__(name, n_classes=2, **kw) - self.scorers = [self.f1_scorer] - self.load_data(path, max_seq_len) - self.sentences = self.train_data_text[0] + self.val_data_text[0] - - def load_data(self, path, max_seq_len): - tr_data = load_tsv(self._tokenizer_name, os.path.join(path, "train.tsv"), - max_seq_len, s1_idx=3, s2_idx=4, targ_idx=5, skip_rows=1) - val_data = load_tsv(self._tokenizer_name, os.path.join(path, "dev.tsv"), - max_seq_len, s1_idx=3, s2_idx=4, targ_idx=5, skip_rows=1) - te_data = load_tsv(self._tokenizer_name, os.path.join(path, 'test.tsv'), - max_seq_len, s1_idx=1, s2_idx=2, targ_idx=None, idx_idx=0, skip_rows=1) - self.train_data_text = tr_data - self.val_data_text = val_data - self.test_data_text = te_data - - def _make_instance(input1, input2, label): - """ from multiple types in one column create multiple fields """ - d = {} - d["input1"] = sentence_to_text_field(input1, indexers) - d["input2"] = sentence_to_text_field(input2, indexers) - d["labels"] = LabelField(label, label_namespace="labels", - skip_indexing=True) - d['sent1_str'] = MetadataField(" ".join(input1[1:-1])) - d['sent2_str'] = MetadataField(" ".join(input2[1:-1])) - return Instance(d) - - - def get_metrics(self, reset=False): - '''Get metrics specific to the task''' - f1 = self.f1_scorer.get_metric(reset)[2] - return {'f1': f1} -``` - -Phew! Now, you also have to add the models you're going to use for your task, which lives in [`jiant/models/py`](https://github.com/nyu-mll/jiant/blob/master/jiant/models.py). - -Since our task type is PairClassificationTask, a well supported type of task, we can skip this step. However, if your task type is not well supported (or you want to try a different sort of model), in `jiant/models/models.py`, you will need to change the `build_task_specific_module` function to include a branch for your logic. -```python - def build_task_specific_modules( - task, model, d_sent, d_emb, vocab, embedder, args): - task_params = model._get_task_params(task.name) - if isinstance(task, NewTypeOfTask): - hid2voc = build_new_task_specific_module_type(task, d_sent, args) - setattr(model, '%s_mdl' % task.name, hid2voc) -``` - -You will also need to modify the `forward` function in `jiant/models.py` (again, not if you're inheriting from a well-supported task type!), which consist of passing your inputs into a sentence encoder and then through the task specific module you had coded up before. The model will receive the task class you created and a batch of data, where each batch is a dictionary with keys of the Instance objects you created in preprocessing, as well as a predict flag that indicates if your forward function should generate predictions or not. - - -```python - elif isinstance(task, NewTypeOfTask): - out = self._new_task_forward(batch, task, predict) -``` - -Of course, don't forget to define your task-specific module building function! You should pass whatever you need to update_metrics into the `out` dictionary, since this is what's getting passed into `update_metrics` by the trainer. - -```python - def _new_task_forward(self, batch, task, predict): - sent1, mask1 = self.sent_encoder(batch['input1'], task) - sent2, mask2 = self.sent_encoder(batch['input2'], task) - classifier = self._get_classifier(task) - logits = classifier(sent1, sent2, mask1, mask2) - out['loss'] = F.mse_loss(logits, labels) - out["logits"] = logits - return out -``` -Finally, all you have to do is add the task to either the `pretrain_tasks` or `target_tasks` parameter in the config file, and viola! Your task is added. - -# Notes - -## `boundary_token_fn` - -This method applies boundary tokens (like SOS/EOS) to the edges of your text. It also, for BERT and XLNet, applies tokens like [SEP] that delimit the two halves of a two-part input sequence. So, if you'd like to feeding a two-part input into a BERT/XLNet model as a single sequence, create two token sequences, and feed them to `boundary_token_fn` as two arguments. diff --git a/tutorials/setup_tutorial.md b/tutorials/setup_tutorial.md deleted file mode 100644 index 408a4c39e..000000000 --- a/tutorials/setup_tutorial.md +++ /dev/null @@ -1,285 +0,0 @@ -# Tutorial: Getting Started - - -Wecome to `jiant`! Let's help get you set up and running a demo experiment! - -## 1. Install - -First off, let's make sure you've the full repository, including all the git submodules. - -This project uses submodules to manage some dependencies on other research code, in particular for loading CoVe, GPT, and BERT. To make sure you get these repos when you download `jiant`, add `--recursive` to your `clone` command: - -``` -git clone --branch v1.3.2 --recursive https://github.com/nyu-mll/jiant.git jiant -``` -This will download the full repository and load the 1.3.2 release of `jiant`. If you already have `jiant` downloaded locally, you can switch to the 1.3.2 release with -``` -git checkout tags/v1.3.2 -b 1.3.2_master -``` -This will create a branch called 1.3.2_master with HEAD at version 1.3.2. If you already cloned and just need to get the submodules, you can run: - -``` -git submodule update --init --recursive -``` - -Now, let's get your environment set up. Make sure you have `conda` installed (you can find a tutorial [here](https://docs.conda.io/projects/conda/en/latest/user-guide/install/)), then run: - -``` -conda env create -f environment.yml -``` - -Make sure to activate the environment by running: - -``` -conda activate jiant -``` - -before running any `jiant` code. (To deactivate run: `source deactivate`) - -If you are unable to use `conda` for any reason, it should be possible to install all of the necessary dependencies using pip or other tools, but you'll be on your own. Consult [`environment.yml`](https://github.com/nyu-mll/jiant/blob/v1.3.2/environment.yml) for a full list of requirements. If you have access to Docker, you may alse be able to make use of the [`Dockerfile`](https://github.com/nyu-mll/jiant/blob/v1.3.2/Dockerfile), which we use to set up `jiant` on new cloud machines when running tests. - -Some requirements may only be needed for specific configurations. If you have trouble installing a specific dependency and suspect that it isn't needed for your use case, create an issue or a pull request, and we'll help you get by without it. - -Once you have the environment set up, you will also need to install dependencies for `nltk` if you do not already have them: -``` -python -m nltk.downloader perluniprops nonbreaking_prefixes punkt -``` - -And if you want to use GPT, you should also download spaCy packages: - -``` -python -m spacy download en -``` - -### Notebooks - -If you plan to use Jupyter Notebooks with jiant (you should!), make sure that you register a kernel that runs in your conda environment. Do: - -``` -ipython kernel install --user --name=jiant -``` - -And the next time you start a notebook server, you should see `jiant` as an option under "Kernel -> Change kernel". - -### Optional - -If you'll be using GPT, BERT, or other models supplied by `transformers`, then you may see speed gains from installing NVIDIA apex, following the instructions here: - -https://github.com/NVIDIA/apex#linux - -## 2. Getting data and setting up our environment - - In this tutorial, we will be working with GLUE data. -The repo contains a convenience Python script for downloading all [GLUE](https://gluebenchmark.com/) and [SuperGLUE](https://super.gluebenchmark.com/) tasks: - -``` -python scripts/download_glue_data.py --data_dir data --tasks all -python scripts/download_superglue_data.py --data_dir data --tasks all -``` - -We also support quite a few other data sources (check [here](https://jiant.info/documentation#/?id=data-sources) for a list). - - -Finally, you'll need to set a few environment variables in [user_config_template.sh](https://github.com/nyu-mll/jiant/blob/master/user_config_template.sh), which include: - - -* `$JIANT_PROJECT_PREFIX`: the directory where things like logs and model checkpoints will be saved. -* `$JIANT_DATA_DIR`: location of the data you want to train and evaluate on. As a starting point, this is often the directory created by the GLUE or SuperGLUE data downloaders. Let's use the `data/` directory for GLUE for now. -* `$WORD_EMBS_FILE`: location of any word embeddings you want to use (not necessary when using ELMo, GPT, or BERT). You can download GloVe (840B) [here](http://nlp.stanford.edu/data/glove.840B.300d.zip) or fastText (2M) [here](https://s3-us-west-1.amazonaws.com/fasttext-vectors/crawl-300d-2M.vec.zip). - - -To avoid having your custom paths overwritten by future updates, you should save a copy of this file as `user_config.sh` (or something similar, but a file with the name `user_config.sh` will be automatically ignored by git). -Before running any experiments in a new terminal session, you should run this command to set the relevant environment variables for your session: - -``` -source user_config.sh -``` - -To remember to do this, it can help to run commands like this by default: - -``` -source user_config.sh; python main.py ... -``` - -Alternately, we offer a more permanent solution for `bash` users. Run - -``` -source scripts/export_from_bash.sh -``` - -from the root of the `jiant` directory, which adds the source command directly to your machine's `.bashrc` or `.bash_profile` file. - -Now that we've set up the environment, let's get started! - -## 3. Running our first experiment - -### 3.a) Configuring our experiment - -Here, we'll try pretraining in a multitask setting on SST and MRPC and then finetuning on STS-B and WNLI separately using a BiLSTM sentence encoder and word embeddings trained from scratch. -This is almost exactly what is specified in `jiant/config/demo.conf`, with one major change. From here, we suggest you to go to [`jiant/config/demo.conf`](https://github.com/nyu-mll/jiant/blob/master/jiant/config/demo.conf), make a copy called `jiant/config/tutorial.conf`, and follow along - we'll explain everything that is in the file in a bit. - -``` -cp jiant/config/demo.conf jiant/config/tutorial.conf -``` - -Next, we need to make a configuration file that defines the parameters of our experiment. `jiant/config/defaults.conf` has all the documentation on the various parameters (including the ones explained below). Any config file you create should import from `jiant/config/defaults.conf`, which you can do by putting the below at the top of your config file. - -``` -include "defaults.conf" -``` - -Some important options include: - -* `sent_enc`: If you want to train a new sentence encoder (rather than using a loaded one like BERT), specify it here. This is the only part of the `jiant/config/demo.conf` that we should change for our experiment since we want to train a biLSTM encoder. Thus, in your `jiant/config/tutorial.conf`, set `sent_enc=rnn`. -* `pretrain_tasks`: This is a comma-delimited string of tasks. In `jiant/config/demo.conf`, this is set to "sst,mrpc", which is what we want. Note that we have `pretrain_tasks` as a separate field from `target_tasks` because our training loop handles the two phases differently (for example, multitask training is only supported in pretraining stage). Note that there should not be a space in-between tasks. -* `target_tasks`: This is a comma-delimited string of tasks you want to fine-tune and evaluate on (in this case "sts-b,wnli"). -* `input_module`: This is a string specifying the type of (contextualized) word embedding you want to use. In `jiant/config/demo.conf`, this is already set to `scratch`. -* `val_interval`: This is the interval (in steps) at which you want to evaluate your model on the validation set during pretraining. A step is a batch update. -* `exp_name`, which expects a string of your experiment name. -* `run_name`, which expects a string of your run name. -The main differences between an experiment and a run is that all runs in an experiment will have the same preprocessing (which may include tokenization differences), while runs his a specific experiment (which may differ from other runs by learning rate or type of sentence encoder, for example, your run name could be `rnn_encoder` for a run with a biLSTM sentence encoder). - -Additionally, let's suppose we want to have parameters specific to the STS-B task. Then, we can simply specify them as here: - -```python - -sts-b += { - classifier_hid_dim = 512 - pair_attn = 0 - max_vals = 16 - val_interval = 10 -} - -``` - -Your finished product should look like the below: - -``` -include "defaults.conf" // relative path to this file - -// write to local storage by default for this demo -exp_name = jiant-demo -run_name = mtl-sst-mrpc - -cuda = -1 -random_seed = 42 - -load_model = 0 -reload_tasks = 0 -reload_indexing = 0 -reload_vocab = 0 - -pretrain_tasks = "sst,mrpc" -target_tasks = "sts-b,commitbank" -classifier = mlp -classifier_hid_dim = 32 -max_seq_len = 10 -max_word_v_size = 1000 -pair_attn = 0 - -input_module = scratch -d_word = 50 - -sent_enc = rnn -skip_embs = 0 - -batch_size = 8 - -val_interval = 50 -max_vals = 10 -target_train_val_interval = 10 -target_train_max_vals = 10 - -// Use += to inherit from any previously-defined task tuples. -sts-b += { - classifier_hid_dim = 512 - pair_attn = 0 - max_vals = 16 - val_interval = 10 -} -``` - -Now we get on to the actual experiment running! -To run the experiment, you can simply run the below command via command line, or use a bash script. - - You can use the `--overrides` flag to override specific variables. For example: - -```sh -python main.py --config_file jiant/config/tutorial.conf \ - --overrides "exp_name = my_exp, run_name = foobar" -``` - -will run the demo config, but write output to `$JIANT_PROJECT_PREFIX/my_exp/foobar`. -Note that cuda=-1 means that we do not use GPU. Jiant uses DataParallel to help with memory constraints, which may be useful if you are running on a multi-GPU machine. Refer to the documentation on the settings for the cuda variable in jiant/config/defaults.conf. - -### 3.b) Understanding the output logs - -We support Tensorboard, however, you can also look at the logs to make sure everything in your experiment is running smoothly. - -There's a lot going on here (including some debugging information that we're working on suppressing), but a lot of it is useful. The logs include: - -* The process of setting up and loading tasks -* Restoring checkpoints (if applicable) -* Indexing your data into AllenNLP instances for preparation for training. -* Printing out the model architecture -* When you get to training stage, updates of the current progress and validation. - -One important thing to notice is that during training, the updates will swap between sst and mrpc. This is because for each training batch, we sample the tasks based on a parameter you can set in your experiment `weighting_method`, which is automatically set to proportional (so the larger the task, the larger the probablty it will get sampled for a batch). - -After validating, you will see something like this: -``` -07/11 07:40:02 AM: Updating LR scheduler: -07/11 07:40:02 AM: Best result seen so far for macro_avg: 0.271 -07/11 07:40:02 AM: # validation passes without improvement: 1 -07/11 07:40:02 AM: sts-b_loss: training: 0.158664 validation: 0.165524 -07/11 07:40:02 AM: macro_avg: validation: 0.179073 -07/11 07:40:02 AM: micro_avg: validation: 0.179073 -07/11 07:40:02 AM: sts-b_corr: training: 0.078465 validation: 0.179073 -07/11 07:40:02 AM: sts-b_pearsonr: training: 0.087550 validation: 0.189559 -07/11 07:40:02 AM: sts-b_spearmanr: training: 0.069380 validation: 0.168587 -07/11 07:40:02 AM: Global learning rate: 0.0003 -07/11 07:40:02 AM: Saved checkpoints to coreference_exp/my_exp/foobar -07/11 07:40:02 AM: ***** Step 90 / Validation 9 ***** -. -. -. - -``` - -There are two sets of losses and scores outputted for the two tasks. This is because we're doing multitask learning in this phase. - -Then, after the pretraining phase, during target task training, you will see updates for only one task at a time, and after each validation, only scores for that one task. - -Lastly, we will evaluate on the target tasks, and write the results for test in your run directory. -You should see something like this: - -``` -07/11 07:40:04 AM: Evaluating on: commitbank, split: val -07/11 07:40:04 AM: Task 'commitbank': sorting predictions by 'idx' -07/11 07:40:04 AM: Finished evaluating on: commitbank -07/11 07:40:04 AM: Writing results for split 'val' to coreference_exp/my_exp/results.tsv -07/11 07:40:04 AM: micro_avg: 0.473, macro_avg: 0.473, commitbank_accuracy: 0.679, commitbank_f1: 0.473, commitbank_precision: 0.452, commitbank_recall: 0.496 -07/11 07:40:04 AM: Loaded model state from coreference_exp/my_exp/foobar/sts-b/model_state_target_train_val_10.best.th -07/11 07:40:04 AM: Evaluating on: sts-b, split: val -07/11 07:40:06 AM: Task 'sts-b': sorting predictions by 'idx' -07/11 07:40:06 AM: Finished evaluating on: sts-b -07/11 07:40:06 AM: Writing results for split 'val' to coreference_exp/my_exp/results.tsv -07/11 07:40:06 AM: micro_avg: 0.271, macro_avg: 0.271, sts-b_corr: 0.271, sts-b_pearsonr: 0.279, sts-b_spearmanr: 0.263 -07/11 07:40:06 AM: Done! -``` - -After running this experiment, you should have in your run directory: - -* a checkpoint of the best model state (based on your scores) for both pretraining and target task training phase. The target task checkpoints will be under a subdirectory of the target tasks in the run directory, including checkpoints for metrics, model states, training states, and task states at each epoch. -* a `log.log` file which contains all the logs -* `params.conf` (a saved version of the parameters used) -* written predictions for test for each of the target trained tasks (with file names `{task_name}-test.tsv`) -* a saved checkpoint of your best validation metric. -* A `tensorboard` directory that logs the runs from train and val for all task-specific metrics. Note that right now we do not support logging for macro and micro averages. - -Additionally, the validation scores will be written in `results.tsv` in your experiment directory with the name of the run it belongs to. - -And there you have it! Your first experiment. -If you are looking for where to go next, check out our documentation [here](https://jiant.info/documentation/#/)! - -Happy `jiant`ing! diff --git a/user_config_template.sh b/user_config_template.sh deleted file mode 100644 index 679b12937..000000000 --- a/user_config_template.sh +++ /dev/null @@ -1,40 +0,0 @@ -#!/bin/bash - -# Default environment variables for JSALT code. May be overwritten by user. -# See https://github.com/nyu-mll/jiant for more. - -# DO NOT COMMIT CHANGES TO THIS FILE! -# Make a local copy and follow the instructions below. - -# Copy this to /etc/profile.d/ to auto-set environment vars on login. -# Or, make a copy of this, customize, and run immediately before the training -# binary: -# cp user_config_template.sh user_config.sh -# source user_config.sh; python main.py --config jiant/config/demo.conf \ -# --overrides "do_pretrain = 0" -# ... or use scripts/export_from_bash.sh to set BASH up to run source automatically. - -# (You can use a custom filename too, but user_config.sh will automatically be ignored by git.) - -## -# Example of custom paths for a local installation: -# export JIANT_PROJECT_PREFIX=/Users/Bowman/Drive/JSALT -# export JIANT_DATA_DIR=/Users/Bowman/Drive/JSALT/jiant/glue_data - -# The base directory for model output. -export JIANT_PROJECT_PREFIX=~ - -# Base directory in which to look for raw data subdirectories. This -# could be the glue_data directory created by download_glue_data.py. -export JIANT_DATA_DIR=~ - -# A word embeddings file in GloVe/fastText format. Not used when using -# ELMo, GPT, or BERT. To use more than one different set of embeddings -# in your environment, create an additional environment variable (like) -# FASTTEXT_WORD_EMBS_FILE, and reference it in each of your .conf config -# files with a line like: -# word_embs_file = ${FASTTEXT_WORD_EMBS_FILE} -export WORD_EMBS_FILE=None - -# Optional: -# echo "Loaded custom config."