Home¶
Welcome to bnelearn’s documentation! bnelearn is a framework for equilibrium learning in sealed-bid auctions and other markets that can be modeled as Bayesian Games.
This is a work in progress, so the documentation is still incomplete, and may even be outdated or specific to our local deployments in some places. We’ll be working to bring the documentation up to paar in the near future. If you need additional help in the meantime, please get in touch with one of the maintainers.
The public version of the bnelearn repository is hosted at https://github.com/heidekrueger/bnelearn. Development is ongoing via a private GitLab repository on our university server. If you have questions, find an error, or want to contribute, please get in touch via the Issues on the GitHub repository above, or email one of the maintainers.
You can find the installation instructions at Installation and Reproduction Instructions.
A quickstart guide is provided at Quickstart.
Background information can be found under Auction Theory and Equilibrium Computation.
Installation and Reproduction Instructions¶
These are minimal instructions to install dependencies and run the scripts to reproduce the results presented in our paper.
Prerequesites¶
Current parameter settings assume that you are running on a Unix system with a cuda-enabled Nvidia GPU with at least 11GB GPU-RAM, and that the root directory (containing this readme file) is located at ~/bnelearn. On a system without a GPU (but at least 11GB of available RAM), everything should work, but you will experience significantly longer runtimes. On systems with less GPU-RAM, standard configurations may fail, in that case try adjusting the batch_size and eval_batch_size parameters in the run-scripts (and possibly the tests). Everything should likewise run on Windows, but you may need to change the output directories manually.
Installation¶
bnelearn
mainly runs on top of pytorch
and python. The repository was extensively tested with python 3.9 and pytorch 1.10 on a Ubuntu system.
The package should be cross-platform compatible, but we can make no guarantees. (A limited feature set has been tested on Windows 11.)
Installation instructions for Ubuntu using conda:
Install Python (tested on 3.9) and pip, we recommend using a separate environment using conda or virtualenv. Assuming you have a running installation of conda, make a new environment:
`conda create -n bnelearn-test python=3.9 pip`
Then activate your environment via`conda activate bnelearn`
Optional – you can skip directly to step 3, but this will install the package with a reduced feature set (e.g. no GPU support, no commercial solvers, no development extras.) Make sure you are using the correct version of pip ()`which pip` should point to your new conda environment!) and install the remaining requirements via
pip install -r requirements.txt
. This will install all requirements, including GPU-enabled pytorch, external solvers required for some combinatorial auctions and development tools. Note thatrequirements.txt
will pull the latest stable torch version with cuda that is available at the time of writing (July 2021). You may want to manually install the latest version available for your system, see https://pytorch.org/get-started/locally/ for details.Install the bnelearn package via
pip install -e .
.Test your installation via
pytest
. If all tests pass, everything was successfull. You may also see ``SKIP``s or ``XFAIL``s: In this case, the, installation seems to work, but the tests have determined that you are missing some optional requirements for advanced features, or that your system does not support cuda. In this case, not all features may be available to you.
The framework conceptually consists of the following
A python package
bnelearn
in the./bnelearn
subdirectory.Some User-code scripts in
./scripts
.Jupyter notebooks in the
./notebooks
directory that trigger experiments and log results to subdirectories (or other places) in tensorboard format.The
R
subdirectory contains scripts for parsing tensorboard logs into R dataframes, in order to create pretty figures. Some of this functionality uses r-tensorflow, see source code for installation instructions.
Running the software¶
Navigate to your local
bnelearn
folder (in the following:.
).Activate the
bnelearn
conda-env:conda activate bnelearn
.Execute one of the scripts in the scripts directory, or run a jupyter lab instance to run of the notebooks in the notebooks directory.
Experiment logging¶
On the fly logging: Results of script and notebook experiments are written to a subdirectory as specified in each script or notebook. To view the results or monitor training process, start a tensorboard instance:
Navigate to your experiment output directory.
In another terminal window, activate the
bnelearn
conda env as well:activate bnelearn
.Start a tensorboard instance, pointing at the relevant subdirectory for your experiment (tensorboard can simultaneously display multiple runs of the same experiment.) I.e. if you’re interested in fpsb experiments and your directory structure is
./ | *---* notebooks/ | *---* fpsb/ | *--- run1/ *--- run2/
This folder structure should be used for work in progress. Then start tensorboard using
tensorboard --logdir fpsb [--port 6006]
The standard port is 6006, but each user should use their own port to enable different sessions. The tensorboard server is then accessible at http://localhost:6006.
Quickstart¶
Let us take a look at how to learn in one of the predefined auction games with one of the predefined algorithms.
The commands below can be used to reproduce the results published in (Bichler et al., 2021). All references refer to the numbering in that paper.
(Note: as of December 2022, another paper based on bnelearn
is forthcoming in the INFORMS Journal of computing. Reproduction instruction for that paper will be hosted in a separate repository published by INFORMS.)
Reproduction Instructions for Bichler et al. (2021)¶
You can then run the experiments underlying the tables and figures in the main paper via python run_experiments_npga.py
(see run_experiments_npga.py). The standard configuration of the file reruns the experiments behind Figure 3, i.e., one run each for all combinations of the correlation strength and the risk parameter. To run the other experiments reported in the paper, make the following changes in lines 17 to 34:
For the experiments underlying Figure 2, set
n_runs = 10
,gammas = [0.5]
,payment_rules = ['nearest_vcg']
.For the experiments underlying Table 1, set
n_runs = 10
,risks = [1.0]
,gammas = [0.5]
,payment_rules = ['vcg', 'nearest_bid', 'nearest_zero', 'nearest_vcg', 'first_price']
.
To run the other experiments reported in the Supplementary Information, make the following changes:
For the experiments underlying Table S.1, set
n_runs = 10
,risks = [1.0]
or[0.5]
,gammas = [0.0]
,payment_rules = ['first_price']
,corr_models = ['independent']
,experiment_type = 'single_item_uniform_symmetric'
or'single_item_gaussian_symmetric'
and additionally supply the corresponding number of bidders via then_players
parameter to theset_setting()
call.For the experiments underlying Figure S.1, set
n_runs = 10
,risks = [1.0]
,gammas = [0.0]
,payment_rules = ['first_price']
,corr_models = ['independent']
,experiment_type = 'single_item_gaussian_symmetric
and additionally supply the number of bidders vian_players = 10
within theset_setting()
call.For the experiments underlying Table S.2, set
n_runs = 10
,risks = [1.0]
,gammas = [None]
(fallback to default),payment_rules = ['first_price']
for the Affiliated values setting and'second_price'
for the Common value settings,corr_models = [None]
(fallback to default),experiment_type = 'affiliated_observations'
or'mineral_rights'
and additionally supply the corresponding number of bidders via then_players
parameter to theset_setting()
call.For the experiments underlying Table S.3, set
n_runs = 10
,risks = [1.0]
,gammas = [0.0]
,payment_rules = ['first_price', 'uniform', 'vcg']
,corr_models = ['independent']
,experiment_type = 'multiunit'
and additionally supply the corresponding number of bidders via then_players
parameter and the number of units via then_units
parameter to theset_setting()
call.For the experiments underlying Figure S.2, make the corresponding changes to the previous experiments.
For the experiments underlying Figure S.3, make the corresponding changes to the previous experiments and set
corr_models = ['additive']
.For the experiments underlying Figure S.2, make the corresponding changes to the previous experiments.
Logs will be written into the experiments
subdirectory. While the experiments are running, you can examine the training progress via tensorboard --logdir experiments
.
Running Experiments for Learning with PSO¶
You can then run the experiments for particle swarm optimization (from Kohring et al., 2022) via python run_experiments_pso.py
(see run_experiments_pso.py).
Running Experiments for Learning in Contests¶
You can then run the experiments for particle swarm optimization via python run_experiments_contests.py
(see run_experiments_contests.py).
Auction Theory and Equilibrium Computation¶
1. Background¶
The computation and analysis of equilibrium states in strategic settings is of utmost importance in the economic sciences. However, equilibria in many markets remain poorly understood. The computational complexity of finding Nash equilibria is known to be PPAD complete even for finite normal form games (NFG), a class that is considered to be hard unless P = NP (Daskalakis et al. 2009). Despite these hardness results for the worst case, equilibrium computation has become tenable for NFGs of moderate sizes in recent years. Auction markets are of a particular interest to economists and policymakers, as a precise understanding of strategic behavior in proposed auction markets would be invaluable in the design and implementation market mechanisms with certain desiderata. However, the game theoretic properties of auctions are even less amiable to equilibrium computation: Auctions are commonly modeled as Bayesian games with continuous type and action spaces (Harsanyi 1968), resulting in an infinite-dimensional, functional space of possible strategies. Such games are no longer finite, so even Nash’s famous theorem about the existence of equilibria (Nash 1950) no longer holds, and the complexity of finding Bayesian Nash equilibria in auctions may be NP-hard or worse depending on the specifics of the game. In fact, Cai and Papadimitriou (2014) show that in certain combinatorial auctions, the computation of Bayesian Nash (BNE) is at least PP-hard (a complexity class above the polynomial hierarchy), and even certifying or approximating a BNE at a constant approximation bound remains NP-hard. The current understanding of strategic behavior in the field of auction theory therefore relies mainly on equilibria that have been analytically derived. Unfortunately, such results are scarce and elusive for all but a few simple settings.
Most recently, however, there have been a range of first empirical successes in approximating Bayesian Nash equilibria in sealed-bid auctions using computational black-box methods that do not rely on manual mathematical analysis of specific settings (Heymann and Mertikopoulos 2021, Bichler et al. 2021, Bosshard et al. 2020, Li and Wellman 2020) This suggests that the established hardness results may not apply to a wide range of auctions that are of practical interest and that it may be possible to characterize subclasses of continuous Bayesian games for which equilibrium computation may be feasible.
However, the literature on auctions is vast, with many variants of markets that are of interest. This has been a limiting factor for research in equilibrium computation, as each individual study has only been able to investigate new methods in a small number of relevant auction settings due to implementation complexity. Existing equilibrium learning methods rely on simulating very large numbers of auctions, which has required computational optimizations that have often been hand tailored to specific classes of auctions or even the specific setting at hand.
To facilitate future research in equilibrium computation in auctions, we propose consolidating a wide set of auction settings into a single benchmark suite with a common, modular, extensible and performant programming interface. To this end, we present our open-source package bnelearn, which provides a GPU-accelerated framework for equilibrium computation in sealed-bid auctions and related (Bayesian and complete-information) games. Using bnelearn, researchers working on novel equilibrium learning rules will have access to a wide selection of implemented auction settings with or without existing equilibria as well as to an ecosystem of metrics and tools that facilitate analysis. To the authors’ knowledge, bnelearn comprises the largest and most complete suite of implementations of sealed-bid auctions and their known equilibria, collecting
In addition to researchers in equilibrium computation, we expect that such a framework will also be useful to practitioners of auction theory in the economic sciences: Given the fact that existing approaches have been empirically demonstrated to converge to approximate equilibria in a wide range of auction settings, and (approximate) error bounds can be calculated for candidate solutions, bnelearn enables analyses of strategic behavior in markets that elude analytical equilibrium analysis. As an example, in (Bichler et al. 2021), we were empirically able to quantify the effects of correlation between bidders on revenue and economic efficiency in equilibrium of small combinatorial auctions with core-selecting payment rules.
2. Problem Statement¶
2.1 Model of an Auction Game¶
We consider sealed-bid auctions as special cases of Bayesian games. In such games, an auctioneer aims to sell \(m\) goods to \(n\) competing buyers. These buyers each submit bids based on their private information. Based on these bids, the auctioneer then uses an auction mechanism to allocate the goods to the buyers and determine what prices to charge the winners. The most general case of such an auction game can be formalized as the tuple \(G = (n, m, \mathcal{V}, \mathcal{O}, F, \mathcal{A}, x, p, u)\), where
\(n\) is the number of participating bidders or agents. We denote the set of bidders by \(\mathcal{I} = \lbrace 1, \dots, n\rbrace\) and use the letter \(i\) to index it.
\(m\) is the number of goods to be sold. When goods are heterogenous, we further denote by \(\mathcal{K} = 2^{[m]}\) the set of bundles of goods, and index it by \(k\). When goods are homogenous, we instead use \(\mathcal{K} = {[m]} \cup \{0\}\) to describe the possible cardinalities of subsets of the goods.
\(\mathcal{V} = \mathcal{V}_1 \times \dots \times \mathcal{V}_n\) describes the set of possible valuations of the bidders: Each bidder \(i\) may be potentially interested in a subset \(\mathcal{K}_i \subseteq \mathcal{K}\) of the possible bundles. Writing \(K_i = \left\lvert \mathcal{K}_i \right\rvert\) for it’s cardinality, \(\mathcal{V}_i \subseteq \mathbb{R}^{K_i}_{+}\) then is the set of possible valuation vectors for agent \(i\). For example, in an auction of two heterogenous items \(\{a, b\}\), we might have \(\mathcal{V}_i = \mathbb{R}^4_+\) and a vector \(v_i = (0, 1, 2, 5)\) would indicate agent \(i\)’s valuations for winning the empty bundle, only item \(a\), only item \(b\), or both items, respectively. Note that in some cases, bidders may not directly observe their true valuations \(v_i\), but may only have access to partial information about them:
\(\mathcal{O} = \mathcal{O}_1 \times \dots \times \mathcal{O}_n\) describes the set of possible signals or observations of private information that the bidders have access to. In the private values model, where bidders have full information about their valuations, we have \(o_i = v_i\).
\(F\) is the cumulative density function of the joint prior distribution over bidders’ types, given by tuples \((o_i, v_i)\) of observations and valuations: \(F: \mathcal V \times \mathcal O \rightarrow [0, 1]\). It’s probability density function will be denoted by \(f\) and we state no further assumptions on the prior, thus, allowing for arbitrary correlations. Its marginals are denoted by \(f_v\), \(f_{o_i}\), etc. and its conditionals by \(f_{v_i\vert o_i}\).
\(\mathcal{A} = \mathcal{A}_1 \times \dots \times \mathcal{A}_n = \mathbb{R}^n_{\geq 0}\) are the available actions or bids to the bidders. These must be decided on based on the strategy \(\beta_i: \mathcal{O}_i \rightarrow \mathcal{A}_i\) with the information they have available, namely their observations \(o_i\).
\(x = (x_1, \dots, x_n) \in \{0, 1\}^{|\mathcal K|}\) and \(p = (p_1, \dots, p_n) \in \mathbb{R}^n\) describe the allocations and the payments that are determined by the mechanism after bids \(b \in \mathcal{A}\) have been reported. An allocation constitutes a partition of the \(m\) items, where bidder \(i\) is allocated the bundle \(x_i\). In the simplest case, the allocations would be chosen such that the seller revenue (the sum of all bidders’ payments) is maximized when bidders pay what they report. This is known as the first-price sealed bid auction.
\(u = (u_1, \dots, u_n)\) then is the utility vector of the bidders, where bidder \(i\)’s utility \(u_i(v_i, b)\) depends on their own valuation but all bidders’ actions. Assuming the other bidders follow \(\beta\), bidder \(i\)’s interim utility is then defined as the expected utility of choosing a bid \(b_i\) conditioned on their observation \(o_i\):
\[\overline{u}_i(o,b_i,\beta_{-i}) = \mathbb{E}_{v_i,o_{-i}|o_i}\left[u_i(v_i, b_i,\beta_{-i}(o_{-i}))\right].\]Accordingly, the interim utility loss \(\overline \ell\) that is incurred by not playing a best response is:
\[\overline \ell (o; b_i, \beta_{-i}) = \sup_{b'_i \in \mathcal A_i} \overline u_i(o_i, b'_i, \beta_{-i}) -\overline u_i(o_i, b_i, \beta_{-i}).\]
Furthermore, the ex-ante utility is defined as \(\tilde{u}_i(\beta_i,\beta_{-i})=\mathbb{E}_{o_i \sim f_{o_i}} [\overline{u}_i(o_i, \beta_{i}(o_i), \beta_{-i})]\), and the ex-ante loss \(\tilde \ell_i(\beta_i, \beta_{-i})\).
The question to be answered now is: “What is the optimal strategy profile for the bidders?” The most common the solution concept for this question is the so-called Bayes-Nash equilibrium: An (interim) \(\epsilon\)-Bayes-Nash equilibrium (\(\epsilon\)-BNE) is a strategy profile \(\beta^* = (\beta^*_1, \dots, \beta^*_n)\) such that no agent can improve their own utility by more than \(\epsilon \geq 0\) by unilaterally deviating from \(\beta^*\):
For \(\epsilon = 0\), the BNE is called exact, or the \(\epsilon\)-prefix is simply dropped. The ex-ante \(\epsilon\)-BNE is defined analogously.
bnelearn¶
bnelearn package¶
Subpackages¶
bnelearn.experiment package¶
Submodules¶
bnelearn.experiment.combinatorial_experiment module¶
This module implements combinatorial experiments. Currently, this is only Local Global experiments as considered by Bosshard et al. (2018).
- Limitations and comments:
Currently implemented for only uniform valuations
Strictly speaking Split Award might belong here (however, implementation closer to multi-unit)
- class bnelearn.experiment.combinatorial_experiment.LLGExperiment(config: ExperimentConfig)[source]¶
Bases:
LocalGlobalExperiment
A combinatorial experiment with 2 local and 1 global bidder and 2 items; but each bidders bids on 1 bundle only. Local bidder 1 bids only on the first item, the second only on the second and global only on both. Ausubel and Baranov (2018) provide closed form solutions for the 3 core selecting rules.
Supports arbitrary number of local bidders, not just two.
- action_size: int¶
- bne_env: AuctionEnvironment¶
- bne_utilities: Tensor¶
- epoch: int¶
- input_length: int¶
- n_models: int¶
- observation_size: int¶
- plot_xmax: float¶
- plot_xmin: float¶
- plot_ymax: float¶
- plot_ymin: float¶
- positive_output_point: Tensor¶
- valuation_size: int¶
- class bnelearn.experiment.combinatorial_experiment.LLGFullExperiment(config: ExperimentConfig)[source]¶
Bases:
LocalGlobalExperiment
A combinatorial experiment with 2 local and 1 global bidder and 2 items.
Essentially, this is a general CA with 3 bidders and 2 items.
Each bidder bids on all bundles. Local bidder 1 has only a value for the first item, the second only for the second and global only on both. This experiment is therefore more general than the LLGExperiment and includes the specific payment rule from Beck & Ott, where the 2nd local bidder is favored (pays VCG prices).
- action_size: int¶
- bne_env: AuctionEnvironment¶
- bne_utilities: Tensor¶
- epoch: int¶
- input_length: int¶
- n_models: int¶
- observation_size: int¶
- plot_xmax: float¶
- plot_xmin: float¶
- plot_ymax: float¶
- plot_ymin: float¶
- positive_output_point: Tensor¶
- pretrain_transform(player_position: int) callable [source]¶
Transformation during pretraining: Bidders are single-minded in this setting.
- valuation_size: int¶
- class bnelearn.experiment.combinatorial_experiment.LLLLGGExperiment(config: ExperimentConfig)[source]¶
Bases:
LocalGlobalExperiment
- A combinatorial experiment with 4 local and 2 global bidder and 6 items; but each bidders bids on 2 bundles only.
Local bidder 1 bids on the bundles {(item_1,item_2),(item_2,item_3)} Local bidder 2 bids on the bundles {(item_3,item_4),(item_4,item_5)} … Gloabl bidder 1 bids on the bundles {(item_1,item_2,item_3,item_4), (item_5,item_6,item_7,item_8)} Gloabl bidder 1 bids on the bundles {(item_3,item_4,item_5,item_6), (item_1,item_2,item_7,item_8)}
No BNE are known (but VCG). Bosshard et al. (2018) consider this setting with nearest-vcg and first-price payments.
- TODO:
Implement eval_env for VCG
- action_size: int¶
- bne_env: AuctionEnvironment¶
- bne_utilities: Tensor¶
- epoch: int¶
- input_length: int¶
- n_models: int¶
- observation_size: int¶
- plot_xmax: float¶
- plot_xmin: float¶
- plot_ymax: float¶
- plot_ymin: float¶
- positive_output_point: Tensor¶
- valuation_size: int¶
- class bnelearn.experiment.combinatorial_experiment.LLLLRRGExperiment(config: ExperimentConfig)[source]¶
Bases:
Experiment
Experiment in an extension of the Local-Global Model with three groups of bidders.
- action_size: int¶
- bne_env: AuctionEnvironment¶
- bne_utilities: Tensor¶
- epoch: int¶
- input_length: int¶
- n_models: int¶
- observation_size: int¶
- plot_xmax: float¶
- plot_xmin: float¶
- plot_ymax: float¶
- plot_ymin: float¶
- positive_output_point: Tensor¶
- valuation_size: int¶
- class bnelearn.experiment.combinatorial_experiment.LocalGlobalExperiment(config: ExperimentConfig, n_players, n_local, valuation_size, observation_size, action_size)[source]¶
Bases:
Experiment
,ABC
This class represents Local Global experiments in general as considered by Bosshard et al. (2018). It serves only to provide common logic and parameters for LLG and LLLLGG.
- action_size: int¶
- bne_env: AuctionEnvironment¶
- bne_utilities: Tensor¶
- epoch: int¶
- input_length: int¶
- n_models: int¶
- observation_size: int¶
- plot_xmax: float¶
- plot_xmin: float¶
- plot_ymax: float¶
- plot_ymin: float¶
- positive_output_point: Tensor¶
- valuation_size: int¶
bnelearn.experiment.configuration_manager module¶
- class bnelearn.experiment.configuration_manager.ConfigurationManager(experiment_type: str, n_runs: int, n_epochs: int, seeds: Optional[Iterable[int]] = None)[source]¶
Bases:
object
The class provides a ‘front-end’ for the whole package. It allows for creation of a full and consistent
ExperimentConfiguration
, as defined by the ExperimentConfig dataclass. It manages all the defaults, including those specific for each experiment type, auto-inits the parameters that are not supposed to be initialized manually, and allows to selectively change any part of the configuration, while also performing a parameter and consistency check before creating the final configuration object.The workflow with the class API is as follows:
Init class object with the experiment type string, n_runs and n_epochs. For possible experiment types see
ConfigurationManager.experiment_types
__init__
calls get_default_config_members method to get default configuration members.Based on the experiment type,
__init__
calls the appropriate ancillary_init_experiment_type
. It sets the default parameters specific for the given experiment type.
(Optional step) Call set_config_member methods (e.g.
set_setting
) in a chain style, each methods allows to selectively set any parameter of a corresponding config member to a new arbitrary value, while leaving all the parameters not specified by the user intact - with their default values.Call the
get_config
method to get a ready configuration object and an experiment class corresponding to the experiment type (the latter needed for an easy instantiation of the Experiment)get_config
calls_post_init
, which inits the parameters which shouldn’t be set manually, checks for consistency between the related parameters and validates whether each parameter is in an appropriate value range. Then, it calls the type specific_post_init_experiment_type
method which performs all the same things, but specific for the experiment type.get_config
creates and returns the final and valid configuration object alongside the experiment class.
Example of class usage:
experiment_config, experiment_class = \ ConfigurationManager( experiment_type='multiunit', n_runs=1, n_epochs=20 ) \ .set_logging(log_root_dir=log_root_dir) \ .set_setting(payment_rule='discriminatory') \ .set_learning(model_sharing=False) \ .set_hardware() \ .get_config() experiment_class(experiment_config).run()
- static compare_two_experiment_configs(conf1: ExperimentConfig, conf2: ExperimentConfig) bool [source]¶
Checks whether two given configurations are identical (deep comparison)
- static experiment_config_could_be_saved_properly(exp_config: ExperimentConfig) bool [source]¶
Tests whether the given config could be serialized and deserialized properly.
- experiment_types = {'affiliated_observations': (<class 'bnelearn.experiment.single_item_experiment.AffiliatedObservationsExperiment'>, <function ConfigurationManager._init_affiliated_observations>, <function ConfigurationManager._post_init_affiliated_observations>), 'all_pay_uniform_symmetric': (<class 'bnelearn.experiment.single_item_experiment.UniformSymmetricPriorSingleItemExperiment'>, <function ConfigurationManager._init_single_item_uniform_symmetric>, <function ConfigurationManager._post_init_single_item_uniform_symmetric>), 'crowdsourcing': (<class 'bnelearn.experiment.single_item_experiment.ContestExperiment'>, <function ConfigurationManager._init_crowdsourcing>, <function ConfigurationManager._post_init_crowdsourcing>), 'llg': (<class 'bnelearn.experiment.combinatorial_experiment.LLGExperiment'>, <function ConfigurationManager._init_llg>, <function ConfigurationManager._post_init_llg>), 'llg_full': (<class 'bnelearn.experiment.combinatorial_experiment.LLGFullExperiment'>, <function ConfigurationManager._init_llg_full>, <function ConfigurationManager._post_init_llg_full>), 'llllgg': (<class 'bnelearn.experiment.combinatorial_experiment.LLLLGGExperiment'>, <function ConfigurationManager._init_llllgg>, <function ConfigurationManager._post_init_llllgg>), 'llllrrg': (<class 'bnelearn.experiment.combinatorial_experiment.LLLLRRGExperiment'>, <function ConfigurationManager._init_llllrrg>, <function ConfigurationManager._post_init_llllrrg>), 'mineral_rights': (<class 'bnelearn.experiment.single_item_experiment.MineralRightsExperiment'>, <function ConfigurationManager._init_mineral_rights>, <function ConfigurationManager._post_init_mineral_rights>), 'multiunit': (<class 'bnelearn.experiment.multi_unit_experiment.MultiUnitExperiment'>, <function ConfigurationManager._init_multiunit>, <function ConfigurationManager._post_init_multiunit>), 'single_item_asymmetric_beta': (<class 'bnelearn.experiment.single_item_experiment.TwoPlayerAsymmetricBetaPriorSingleItemExperiment'>, <function ConfigurationManager._init_single_item_asymmetric_beta>, <function ConfigurationManager._post_init_single_item_asymmetric_beta>), 'single_item_asymmetric_uniform_disjunct': (<class 'bnelearn.experiment.single_item_experiment.TwoPlayerAsymmetricUniformPriorSingleItemExperiment'>, <function ConfigurationManager._init_single_item_asymmetric_uniform_disjunct>, <function ConfigurationManager._post_init_single_item_asymmetric_uniform_disjunct>), 'single_item_asymmetric_uniform_overlapping': (<class 'bnelearn.experiment.single_item_experiment.TwoPlayerAsymmetricUniformPriorSingleItemExperiment'>, <function ConfigurationManager._init_single_item_asymmetric_uniform_overlapping>, <function ConfigurationManager._post_init_single_item_asymmetric_uniform_overlapping>), 'single_item_gaussian_symmetric': (<class 'bnelearn.experiment.single_item_experiment.GaussianSymmetricPriorSingleItemExperiment'>, <function ConfigurationManager._init_single_item_gaussian_symmetric>, <function ConfigurationManager._post_init_single_item_gaussian_symmetric>), 'single_item_uniform_symmetric': (<class 'bnelearn.experiment.single_item_experiment.UniformSymmetricPriorSingleItemExperiment'>, <function ConfigurationManager._init_single_item_uniform_symmetric>, <function ConfigurationManager._post_init_single_item_uniform_symmetric>), 'splitaward': (<class 'bnelearn.experiment.multi_unit_experiment.SplitAwardExperiment'>, <function ConfigurationManager._init_splitaward>, <function ConfigurationManager._post_init_splitaward>), 'tullock_contest': (<class 'bnelearn.experiment.single_item_experiment.ContestExperiment'>, <function ConfigurationManager._init_tullock>, <function ConfigurationManager._post_init_tullock>)}¶
- static get_class_by_experiment_type(experiment_type: str)[source]¶
Given an experiment type, returns the corresponding experiment class which could be initialized
- get_config()[source]¶
Performs the _post_init, creates and returns the final ExperimentConfig object alongside with the appropriate experiment class
- static get_default_config_members() Tuple[RunningConfig, SettingConfig, LearningConfig, LoggingConfig, HardwareConfig] [source]¶
Creates with default (or most common) parameters and returns members of the ExperimentConfig
- static load_experiment_config(experiment_log_dir=None)[source]¶
Retrieves stored configurations from JSON and turns them into ExperimentConfiguration object By default creates configuration from the file stored alongside the running script
- Parameters:
experiment_log_dir – full path except for the file name, current working directory by default
- Returns:
ExperimentConfiguration object
- set_hardware(cuda: bool = 'None', specific_gpu: int = 'None', fallback: bool = 'None', max_cpu_threads: int = 'None')[source]¶
Sets only the parameters of hardware which were passed, returns self
- set_learning(model_sharing: bool = 'None', learner_type: str = 'None', learner_hyperparams: dict = 'None', optimizer_type: str = 'None', optimizer_hyperparams: dict = 'None', scheduler_type: str = 'None', scheduler_hyperparams: dict = 'None', hidden_nodes: List[int] = 'None', pretrain_iters: int = 'None', smoothing_temperature: bool = 'None', batch_size: int = 'None', hidden_activations: List[Module] = 'None', redraw_every_iteration: bool = 'None', mixed_strategy: str = 'None', pretrain_to_bne: int = 'None', value_contest: bool = True)[source]¶
Sets only the parameters of learning which were passed, returns self
- set_logging(enable_logging: bool = 'None', log_root_dir: str = 'None', util_loss_batch_size: int = 'None', util_loss_opponent_batch_size: int = 'None', util_loss_grid_size: int = 'None', eval_frequency: int = 'None', eval_batch_size: int = 'None', plot_frequency: int = 'None', plot_points: int = 'None', plot_show_inline: bool = 'None', log_metrics: dict = 'None', best_response: bool = 'None', save_tb_events_to_csv_aggregate: bool = 'None', save_tb_events_to_csv_detailed: bool = 'None', save_tb_events_to_binary_detailed: bool = 'None', save_models: bool = 'None', save_figure_to_disk_png: bool = 'None', save_figure_to_disk_svg: bool = 'None', save_figure_data_to_disk: bool = 'None', cache_eval_actions: bool = 'None', export_step_wise_linear_bid_function_size: bool = 'None', experiment_dir: str = 'None', experiment_name: str = 'None')[source]¶
Sets only the parameters of logging which were passed, returns self
- set_setting(n_players: int = 'None', payment_rule: str = 'None', risk: float = 'None', n_items: int = 'None', common_prior: Distribution = 'None', valuation_mean: float = 'None', valuation_std: float = 'None', u_lo: list = 'None', u_hi: list = 'None', gamma: float = 'None', correlation_types: str = 'None', correlation_groups: List[List[int]] = 'None', correlation_coefficients: List[float] = 'None', pretrain_transform: callable = 'None', constant_marginal_values: bool = 'None', item_interest_limit: int = 'None', efficiency_parameter: float = 'None', core_solver: str = 'None', tullock_impact_factor: float = 'None', impact_function: str = 'None', crowdsourcing_values: Optional[List] = None)[source]¶
Sets only the parameters of setting which were passed, returns self. Using None here and below Args:
n_players: The number of players in the game. payment_rule: The payment rule to be used. risk: A strictly positive risk-parameter. A value of 1 corresponds to risk-neutral agents,
values <1 indicate risk-aversion.
- common_prior: The common type distribution shared by all players, explicitly given as a
torch.distributions.Distribution
object. Gaussian distribution.- valuation_mean: The expectation of the valuation distribution, when implicitly setting up a
Gaussian distribution.
- valuation_std: The standard deviation of the valuation distribution, when implicitly setting up a
Gaussian distribution.
u_lo: Lower bound of valuation distribution, when implicitly setting up a Uniform distribution. u_hi: Upper bound of valuation distribution, when implicitly setting up a Uniform distribution. gamma: Correlation parameter for correlated value distributions of bidders. (Relevant Settings: LLG) correlation_types: Specifies the type of correlation model. (Most relevant settings: LLG) correlation_groups: A list of lists that ‘groups’ players into correlated subsets. All players
should be part of exactly one sublist. (Relevant settings: LLG)
- correlation_coefficients: List of correlation coefficients for each
group specified with
correlation_groups
.
n_items: Number of items to sell. pretrain_transform: A function used to explicitly give the desired behavior in pretraining for
given neural net inputs. Defaults to identity, i.e. truthful bidding.
- constant_marginal_values: Whether or not the bidders have constant marginal values in
multi-unit auctions.
- item_interest_limit: Whether or not the bidders have a lower demand in units than available in
multi-unit auctions.
efficiency_parameters: Efficiency parameter in split-award auction. core_solver: Specifies which solver should be used to calculate core prices.
Should be one of ‘NoCore’, ‘mpc’, ‘gurobi’, ‘cvxpy’ (Relevant settings: LLLLGG)
- Returns:
self
with updated parameters.
bnelearn.experiment.configurations module¶
This module provides dataclasses that are used to hold configs. The values which are set to None are either not necessary, specific only for certain kinds of experiments or are set later depending on other values
- class bnelearn.experiment.configurations.EnhancedJSONEncoder(*, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, sort_keys=False, indent=None, separators=None, default=None)[source]¶
Bases:
JSONEncoder
- default(o)[source]¶
Implement this method in a subclass such that it returns a serializable object for
o
, or calls the base implementation (to raise aTypeError
).For example, to support arbitrary iterators, you could implement default like this:
def default(self, o): try: iterable = iter(o) except TypeError: pass else: return list(iterable) # Let the base class default method raise the TypeError return JSONEncoder.default(self, o)
- class bnelearn.experiment.configurations.ExperimentConfig(experiment_class: str, running: bnelearn.experiment.configurations.RunningConfig, setting: bnelearn.experiment.configurations.SettingConfig, learning: bnelearn.experiment.configurations.LearningConfig, logging: bnelearn.experiment.configurations.LoggingConfig, hardware: bnelearn.experiment.configurations.HardwareConfig)[source]¶
Bases:
object
- experiment_class: str¶
- hardware: HardwareConfig¶
- learning: LearningConfig¶
- logging: LoggingConfig¶
- running: RunningConfig¶
- setting: SettingConfig¶
- class bnelearn.experiment.configurations.HardwareConfig(cuda: bool, specific_gpu: int, fallback: bool, max_cpu_threads: int, device: str = None)[source]¶
Bases:
object
- cuda: bool¶
- device: str = None¶
- fallback: bool¶
- max_cpu_threads: int¶
- specific_gpu: int¶
- class bnelearn.experiment.configurations.LearningConfig(model_sharing: bool, learner_type: str, learner_hyperparams: dict, optimizer_type: str, optimizer_hyperparams: dict, scheduler_type: str, scheduler_hyperparams: dict, hidden_nodes: List[int], pretrain_iters: int, pretrain_to_bne: int, batch_size: int, smoothing_temperature: float, redraw_every_iteration: bool, mixed_strategy: str, bias: bool, hidden_activations: List[torch.nn.modules.module.Module] = None, value_contest: bool = True)[source]¶
Bases:
object
- batch_size: int¶
- bias: bool¶
- learner_hyperparams: dict¶
- learner_type: str¶
- mixed_strategy: str¶
- model_sharing: bool¶
- optimizer_hyperparams: dict¶
- optimizer_type: str¶
- pretrain_iters: int¶
- pretrain_to_bne: int¶
- redraw_every_iteration: bool¶
- scheduler_hyperparams: dict¶
- scheduler_type: str¶
- smoothing_temperature: float¶
- value_contest: bool = True¶
- class bnelearn.experiment.configurations.LoggingConfig(enable_logging: bool, log_root_dir: str, util_loss_batch_size: int, util_loss_opponent_batch_size: int, util_loss_grid_size: int, eval_frequency: int, eval_batch_size: int, cache_eval_actions: bool, plot_frequency: int, plot_points: int, plot_show_inline: bool, log_metrics: dict, best_response: bool, save_tb_events_to_csv_aggregate: bool, save_tb_events_to_csv_detailed: bool, save_tb_events_to_binary_detailed: bool, save_models: bool, log_componentwise_norm: bool, save_figure_to_disk_png: bool, save_figure_to_disk_svg: bool, save_figure_data_to_disk: bool, experiment_dir: Optional[str] = None, experiment_name: Optional[str] = None)[source]¶
Bases:
object
Controls logging and evaluation aspects of an experiment suite.
If logging is enabled, the experiment runs will be logged to the following directories:
log_root_dir / [setting-specific dir hierarchy determined by Experiment subclasses] / experiment_timestamp + experiment_name / run_timestamp + run_seed
- best_response: bool¶
- cache_eval_actions: bool¶
- enable_logging: bool¶
- eval_batch_size: int¶
- eval_frequency: int¶
- experiment_dir: str = None¶
- experiment_name: str = None¶
- export_step_wise_linear_bid_function_size = None¶
- log_componentwise_norm: bool¶
- log_metrics: dict¶
- log_root_dir: str¶
- plot_frequency: int¶
- plot_points: int¶
- plot_show_inline: bool¶
- save_figure_data_to_disk: bool¶
- save_figure_to_disk_png: bool¶
- save_figure_to_disk_svg: bool¶
- save_models: bool¶
- save_tb_events_to_binary_detailed: bool¶
- save_tb_events_to_csv_aggregate: bool¶
- save_tb_events_to_csv_detailed: bool¶
- util_loss_batch_size: int¶
- util_loss_grid_size: int¶
- util_loss_opponent_batch_size: int¶
- class bnelearn.experiment.configurations.RunningConfig(n_runs: int, n_epochs: int, seeds: Iterable[int] = None)[source]¶
Bases:
object
- n_epochs: int¶
- n_runs: int¶
- seeds: Iterable[int] = None¶
- class bnelearn.experiment.configurations.SettingConfig(n_players: int, n_items: int, payment_rule: str, risk: float, common_prior: torch.distributions.distribution.Distribution = None, valuation_mean: float = None, valuation_std: float = None, u_lo: list = None, u_hi: list = None, gamma: float = None, correlation_types: str = None, correlation_groups: List[List[int]] = None, correlation_coefficients: List[float] = None, pretrain_transform: <built-in function callable> = None, constant_marginal_values: bool = False, item_interest_limit: int = None, efficiency_parameter: float = None, core_solver: str = None, tullock_impact_factor: float = None, impact_function: str = None, crowdsourcing_values: List = None)[source]¶
Bases:
object
- common_prior: Distribution = None¶
- constant_marginal_values: bool = False¶
- core_solver: str = None¶
- correlation_coefficients: List[float] = None¶
- correlation_groups: List[List[int]] = None¶
- correlation_types: str = None¶
- crowdsourcing_values: List = None¶
- efficiency_parameter: float = None¶
- gamma: float = None¶
- impact_function: str = None¶
- item_interest_limit: int = None¶
- n_items: int¶
- n_players: int¶
- payment_rule: str¶
- pretrain_transform: callable = None¶
- risk: float¶
- tullock_impact_factor: float = None¶
- u_hi: list = None¶
- u_lo: list = None¶
- valuation_mean: float = None¶
- valuation_std: float = None¶
bnelearn.experiment.equilibria module¶
This module contains implementations of known Bayes-Nash equilibrium bid functions in several specific settings. Whenever possible, the bid functions are fully vectorized.
NOTE: This module contains a mix of direct implementations of bid functions, and factory methods that create and return the bid function as a callable object.
- bnelearn.experiment.equilibria.bne1_kaplan_zhamir(u_lo: List, u_hi: List)[source]¶
BNE in asymmetric 2-player IPV first-price auctions, when both players have quasilinear-utilities and uniform priors, that do NOT share the same lower bound and are non overlapping.
This setting was analyzed by Kaplan and Zhamir (2014) and was found to have multiple pure BNE. (At least 3).
Reference: Equilibrium 1 of https://link.springer.com/article/10.1007/s40505-014-0049-1
NOTE: this implementation is hard-coded for the bounds used in the paper above, i.e. [0,5] and [6,7], but we do not perform any checks at runtime for performance reasons!
- bnelearn.experiment.equilibria.bne2_kaplan_zhamir(valuation: Tensor, player_position: int, u_lo: List, u_hi: List)[source]¶
BNE in asymmetric 2-player IPV first-price auctions, when both players have quasilinear-utilities and uniform priors, that do NOT share the same lower bound and are nonoverlapping.
This setting was analyzed by Kaplan and Zhamir (2014) and was found to have multiple pure BNE. (At least 3).
Reference: Equilibrium 2 of https://link.springer.com/article/10.1007/s40505-014-0049-1
NOTE: this implementation is hard-coded for the bounds used in the paper above, i.e. [0,5] and [6,7], but we do not perform any checks at runtime for performance reasons!
- bnelearn.experiment.equilibria.bne3_kaplan_zhamir(valuation: Tensor, player_position: int, u_lo: List, u_hi: List)[source]¶
BNE in asymmetric 2-player IPV first-price auctions, when both players have quasilinear-utilities and uniform priors, that do NOT share the same lower bound and are nonoverlapping.
This setting was analyzed by Kaplan and Zhamir (2014) and was found to have multiple pure BNE. (At least 3).
Reference: Equilibrium 3 of https://link.springer.com/article/10.1007/s40505-014-0049-1
NOTE: this implementation is hard-coded for the bounds used in the paper above, i.e. [0,5] and [6,7], but we do not perform any checks at runtime for performance reasons!
- bnelearn.experiment.equilibria.bne_2p_affiliated_values(valuation: Tensor, player_position: int = 0) Tensor [source]¶
Symmetric BNE in the 2p affiliated values model.
Reference: Krishna (2009), Example 6.2
- bnelearn.experiment.equilibria.bne_3p_mineral_rights(valuation: Tensor, player_position: int = 0) Tensor [source]¶
BNE in the 3-player ‘Mineral Rights’ setting.
Reference: Krishna (2009), Example 6.1
- bnelearn.experiment.equilibria.bne_crowdsourcing_symmetric_uniform_cost(valuation: Tensor, v1: float = 0.5, **kwargs)[source]¶
- bnelearn.experiment.equilibria.bne_crowdsourcing_symmetric_uniform_value(valuation: Tensor, v1: float = 1, v2=0, N: int = 0, player_position=0, **kwargs)[source]¶
- bnelearn.experiment.equilibria.bne_fpsb_ipv_asymmetric_uniform_overlapping_priors_risk_neutral(valuation: Tensor, player_position: int, u_lo: List, u_hi: List) Tensor [source]¶
BNE in asymmetric 2-player IPV first-price auctions, when both players have quasilinear-utilities and uniform valuation priors that share the same lower lower bound, but may differ in the upper bound.
Reference: https://link.springer.com/article/10.1007/BF01271133
- bnelearn.experiment.equilibria.bne_fpsb_ipv_symmetric_generic_prior_risk_neutral(valuation: Union[Tensor, ndarray, float], n_players: int, prior_cdf: Callable, **kwargs) Tensor [source]¶
- BNE in symmetric IPV first-price sealed bid auctions with
generic prior value distributions and quasi-linear utilities.
Reference: Krishna (2009), Chapter 2, Proof of Proposition 2.2.
- bnelearn.experiment.equilibria.bne_fpsb_ipv_symmetric_uniform_prior(valuation: Tensor, n: int, r: float, u_lo, u_hi, **kwargs) Tensor [source]¶
BNE in the special case of symmetric FPSB IPV auctions where priors are symmetric uniform.
Compared to the generic case above, we also know this BNE for risk-averse agents.
Reference:
In terms of implementation, note that this equlibrium is fully vectorized.
- bnelearn.experiment.equilibria.bne_splitaward_2x2_1_factory(experiment_config, payoff_dominant: bool = True)[source]¶
Factory method returning the BNE pooling equilibrium in the split-award auction with 2 players and 2 lots (as in Anton and Yao, 1992).
Actually, this is a continuum of BNEs of which this function returns the upper bound (payoff dominant BNE) and the one at the lower bound.
- Returns:
optimal_bid (callable): The equilibrium bid function.
- bnelearn.experiment.equilibria.bne_splitaward_2x2_2_factory(experiment_config)[source]¶
Factory method returning the BNE WTA equilibrium in the split-award auction with 2 players and 2 lots (as in Anton and Yao Proposition 4, 1992).
- Returns:
optimal_bid (callable): The equilibrium bid function.
- bnelearn.experiment.equilibria.bne_symmetric_all_pay_uniform_prior(valuation: Tensor, n_player: int, **kwargs) Tensor [source]¶
bnelearn.experiment.experiment module¶
This module defines an experiment. It includes logging and plotting since they can often be shared by specific experiments.
- class bnelearn.experiment.experiment.Experiment(config: ExperimentConfig)[source]¶
Bases:
ABC
Abstract Class representing an experiment
- action_size: int¶
- bne_env: AuctionEnvironment¶
- bne_utilities: Tensor¶
- epoch: int¶
- input_length: int¶
- n_models: int¶
- observation_size: int¶
- plot_xmax: float¶
- plot_xmin: float¶
- plot_ymax: float¶
- plot_ymin: float¶
- positive_output_point: Tensor¶
- pretrain_transform(player_position: int) callable [source]¶
Some experiments need specific pretraining transformations. In most cases, pretraining to the truthful bid (i.e. the identity function) is sufficient.
- Args:
- player_position (:int:) the player for which the transformation is
requested.
- Returns
(:callable:) pretraining transformation
- run() bool [source]¶
Runs the experiment implemented by this class, i.e. all defined runs.
If a run fails for whatever reason, a warning will be raised and the next run will be triggered until all runs have completed/failed.
- Returns:
success (bool): True if all runs ran successfully, false otherwise.
- valuation_size: int¶
bnelearn.experiment.multi_unit_experiment module¶
In this file multi-unit experiments MultiUnitExperiment
are defined and
their analytical BNEs (if known) are assigned. Also, the SplitAwardExperiment
is implemented as well, as it shares most its properties.
- class bnelearn.experiment.multi_unit_experiment.MultiUnitExperiment(config: ExperimentConfig)[source]¶
Bases:
_MultiUnitSetupEvalMixin
,Experiment
Experiment class for the standard multi-unit auctions.
- action_size: int¶
- b_opt: torch.Tensor¶
- bne_env: AuctionEnvironment¶
- bne_utilities: Tensor¶
- env: Environment¶
- epoch: int¶
- input_length: int¶
- learners: Iterable[learners.Learner]¶
- models: Iterable[torch.nn.Module]¶
- n_models: int¶
- observation_size: int¶
- plot_xmax: float¶
- plot_xmin: float¶
- plot_ymax: float¶
- plot_ymin: float¶
- positive_output_point: Tensor¶
- sampler: ValuationObservationSampler¶
- v_opt: torch.Tensor¶
- valuation_size: int¶
- class bnelearn.experiment.multi_unit_experiment.SplitAwardExperiment(config: ExperimentConfig)[source]¶
Bases:
_MultiUnitSetupEvalMixin
,Experiment
Experiment class of the first-price sealed bid split-award auction.
- action_size: int¶
- b_opt: torch.Tensor¶
- bne_env: AuctionEnvironment¶
- bne_utilities: Tensor¶
- env: Environment¶
- epoch: int¶
- input_length: int¶
- learners: Iterable[learners.Learner]¶
- models: Iterable[torch.nn.Module]¶
- n_models: int¶
- observation_size: int¶
- plot_xmax: float¶
- plot_xmin: float¶
- plot_ymax: float¶
- plot_ymin: float¶
- positive_output_point: Tensor¶
- pretrain_transform(player_position)[source]¶
Some experiments need specific pretraining transformations. In most cases, pretraining to the truthful bid (i.e. the identity function) is sufficient.
- Args:
- player_position (:int:) the player for which the transformation is
requested.
- Returns
(:callable:) pretraining transformation
- sampler: ValuationObservationSampler¶
- v_opt: torch.Tensor¶
- valuation_size: int¶
bnelearn.experiment.single_item_experiment module¶
This module implements Experiments on single items
- class bnelearn.experiment.single_item_experiment.AffiliatedObservationsExperiment(config: ExperimentConfig)[source]¶
Bases:
SingleItemExperiment
A Single Item Experiment that has the same valuation prior for all participating bidders. For risk-neutral agents, a unique BNE is known.
- action_size: int¶
- b_opt: torch.Tensor¶
- bne_env: AuctionEnvironment¶
- bne_utilities: Tensor¶
- env: Environment¶
- epoch: int¶
- input_length: int¶
- learners: Iterable[learners.Learner]¶
- models: Iterable[torch.nn.Module]¶
- n_models: int¶
- observation_size: int¶
- plot_xmax: float¶
- plot_xmin: float¶
- plot_ymax: float¶
- plot_ymin: float¶
- positive_output_point: Tensor¶
- sampler: ValuationObservationSampler¶
- v_opt: torch.Tensor¶
- valuation_size: int¶
- class bnelearn.experiment.single_item_experiment.ContestExperiment(config: ExperimentConfig)[source]¶
Bases:
SymmetricPriorSingleItemExperiment
This class implements a symmetric Contest Experiment
- action_size: int¶
- b_opt: torch.Tensor¶
- bne_env: AuctionEnvironment¶
- bne_utilities: Tensor¶
- env: Environment¶
- epoch: int¶
- input_length: int¶
- learners: Iterable[learners.Learner]¶
- models: Iterable[torch.nn.Module]¶
- n_models: int¶
- observation_size: int¶
- plot_xmax: float¶
- plot_xmin: float¶
- plot_ymax: float¶
- plot_ymin: float¶
- positive_output_point: Tensor¶
- pretrain_transform(player_pos: Optional[int] = None) callable [source]¶
Some experiments need specific pretraining transformations. In most cases, pretraining to the truthful bid (i.e. the identity function) is sufficient.
- Args:
- player_position (:int:) the player for which the transformation is
requested.
- Returns
(:callable:) pretraining transformation
- sampler: ValuationObservationSampler¶
- v_opt: torch.Tensor¶
- valuation_size: int¶
- class bnelearn.experiment.single_item_experiment.GaussianSymmetricPriorSingleItemExperiment(config: ExperimentConfig)[source]¶
Bases:
SymmetricPriorSingleItemExperiment
- action_size: int¶
- b_opt: torch.Tensor¶
- bne_env: AuctionEnvironment¶
- bne_utilities: Tensor¶
- env: Environment¶
- epoch: int¶
- input_length: int¶
- learners: Iterable[learners.Learner]¶
- models: Iterable[torch.nn.Module]¶
- n_models: int¶
- observation_size: int¶
- plot_xmax: float¶
- plot_xmin: float¶
- plot_ymax: float¶
- plot_ymin: float¶
- positive_output_point: Tensor¶
- sampler: ValuationObservationSampler¶
- v_opt: torch.Tensor¶
- valuation_size: int¶
- class bnelearn.experiment.single_item_experiment.MineralRightsExperiment(config: ExperimentConfig)[source]¶
Bases:
SingleItemExperiment
A Single Item Experiment that has the same valuation prior for all participating bidders. For risk-neutral agents, a unique BNE is known.
- action_size: int¶
- b_opt: torch.Tensor¶
- bne_env: AuctionEnvironment¶
- bne_utilities: Tensor¶
- env: Environment¶
- epoch: int¶
- input_length: int¶
- learners: Iterable[learners.Learner]¶
- models: Iterable[torch.nn.Module]¶
- n_models: int¶
- observation_size: int¶
- plot_xmax: float¶
- plot_xmin: float¶
- plot_ymax: float¶
- plot_ymin: float¶
- positive_output_point: Tensor¶
- sampler: ValuationObservationSampler¶
- v_opt: torch.Tensor¶
- valuation_size: int¶
- class bnelearn.experiment.single_item_experiment.SingleItemExperiment(config: ExperimentConfig)[source]¶
Bases:
Experiment
,ABC
- action_size: int¶
- b_opt: torch.Tensor¶
- bne_env: AuctionEnvironment¶
- bne_utilities: Tensor¶
- env: Environment¶
- epoch: int¶
- input_length: int¶
- learners: Iterable[learners.Learner]¶
- models: Iterable[torch.nn.Module]¶
- n_models: int¶
- observation_size: int¶
- plot_xmax: float¶
- plot_xmin: float¶
- plot_ymax: float¶
- plot_ymin: float¶
- positive_output_point: Tensor¶
- sampler: ValuationObservationSampler¶
- v_opt: torch.Tensor¶
- valuation_size: int¶
- class bnelearn.experiment.single_item_experiment.SymmetricPriorSingleItemExperiment(config: ExperimentConfig)[source]¶
Bases:
SingleItemExperiment
A Single Item Experiment that has the same valuation prior for all participating bidders. For risk-neutral agents, a unique BNE is known.
- action_size: int¶
- b_opt: torch.Tensor¶
- bne_env: AuctionEnvironment¶
- bne_utilities: Tensor¶
- env: Environment¶
- epoch: int¶
- input_length: int¶
- learners: Iterable[learners.Learner]¶
- models: Iterable[torch.nn.Module]¶
- n_models: int¶
- observation_size: int¶
- plot_xmax: float¶
- plot_xmin: float¶
- plot_ymax: float¶
- plot_ymin: float¶
- positive_output_point: Tensor¶
- sampler: ValuationObservationSampler¶
- v_opt: torch.Tensor¶
- valuation_size: int¶
- class bnelearn.experiment.single_item_experiment.TwoPlayerAsymmetricBetaPriorSingleItemExperiment(config: ExperimentConfig)[source]¶
Bases:
SingleItemExperiment
A single item experiment where two bidders have different beta priors.
- action_size: int¶
- b_opt: torch.Tensor¶
- bne_env: AuctionEnvironment¶
- bne_utilities: Tensor¶
- env: Environment¶
- epoch: int¶
- input_length: int¶
- learners: Iterable[learners.Learner]¶
- models: Iterable[torch.nn.Module]¶
- n_models: int¶
- observation_size: int¶
- plot_xmax: float¶
- plot_xmin: float¶
- plot_ymax: float¶
- plot_ymin: float¶
- positive_output_point: Tensor¶
- sampler: ValuationObservationSampler¶
- v_opt: torch.Tensor¶
- valuation_size: int¶
- class bnelearn.experiment.single_item_experiment.TwoPlayerAsymmetricUniformPriorSingleItemExperiment(config: ExperimentConfig)[source]¶
Bases:
SingleItemExperiment
- action_size: int¶
- b_opt: torch.Tensor¶
- bne_env: AuctionEnvironment¶
- bne_utilities: Tensor¶
- env: Environment¶
- epoch: int¶
- input_length: int¶
- learners: Iterable[learners.Learner]¶
- models: Iterable[torch.nn.Module]¶
- n_models: int¶
- observation_size: int¶
- plot_xmax: float¶
- plot_xmin: float¶
- plot_ymax: float¶
- plot_ymin: float¶
- positive_output_point: Tensor¶
- sampler: ValuationObservationSampler¶
- v_opt: torch.Tensor¶
- valuation_size: int¶
- class bnelearn.experiment.single_item_experiment.UniformSymmetricPriorSingleItemExperiment(config: ExperimentConfig)[source]¶
Bases:
SymmetricPriorSingleItemExperiment
- action_size: int¶
- b_opt: torch.Tensor¶
- bne_env: AuctionEnvironment¶
- bne_utilities: Tensor¶
- env: Environment¶
- epoch: int¶
- input_length: int¶
- learners: Iterable[learners.Learner]¶
- models: Iterable[torch.nn.Module]¶
- n_models: int¶
- observation_size: int¶
- plot_xmax: float¶
- plot_xmin: float¶
- plot_ymax: float¶
- plot_ymin: float¶
- positive_output_point: Tensor¶
- sampler: ValuationObservationSampler¶
- v_opt: torch.Tensor¶
- valuation_size: int¶
Module contents¶
Main module that handles everything needed for learning.
bnelearn.mechanism package¶
Submodules¶
bnelearn.mechanism.auctions_combinatorial module¶
Auction mechanism for combinatorial auctions (where bidders are interested in bundles of items).
- class bnelearn.mechanism.auctions_combinatorial.CombinatorialAuction(rule='first_price', cuda: bool = True, bundles=None, parallel: int = 1)[source]¶
Bases:
Mechanism
A combinatorial auction, implemented via (possibly parallel) calls to the gurobi solver.
- Args:
rule: pricing rule
- run(bids: Tensor) Tuple[Tensor, Tensor] [source]¶
Performs a general Combinatorial auction
- Args:
- bids: torch.Tensor
of bids with dimensions (batch_size, n_players, 2) [0,Inf]
- bundles: torch.Tensor
of bundles with dimensions (batch_size, 2, n_items), {0,1}
- Returns:
allocation: torch.Tensor, dim (batch_size, n_bidders, 2) payments: torch.Tensor, dim (batch_size, n_bidders)
- class bnelearn.mechanism.auctions_combinatorial.LLGAuction(rule='first_price', cuda: bool = True)[source]¶
Bases:
Mechanism
Implements simple auctions in the LLG setting with 3 bidders and 2 goods. Notably, this is not an implementation of a general Combinatorial auction and bidders do not submit full bundle (XOR) bids: Rather, it’s assumed a priori that each bidder bids on a specific bundle: The first bidder will only bid on the bundle {1}, the second on {2}, the third on {1,2}, thus actions are scalar for each bidder.
For the LLG Domain see e.g. Ausubel & Milgrom 2006 or Bosshard et al 2017
- run(bids: Tensor) Tuple[Tensor, Tensor] [source]¶
Runs a (batch of) LLG Combinatorial auction(s).
We assume n_players == 3 with 0,1 being local bidders and 3 being the global bidder.
Parameters¶
- bids: torch.Tensor
of bids with dimensions (batch_size, n_players, 1)
Returns¶
- (allocation, payments): Tuple[torch.Tensor, torch.Tensor]
- allocation: tensor of dimension (n_batches x n_players x 1),
1 indicating the desired bundle is allocated to corresponding player in that batch, 0 otherwise. (i.e. 1 for player0 means {1} allocated, for player2 means {2} allocated, for player3 means {1,2} allocated.)
- payments: tensor of dimension (n_batches x n_players)
Total payment from player to auctioneer for her allocation in that batch.
- class bnelearn.mechanism.auctions_combinatorial.LLGFullAuction(rule='first_price', cuda: bool = True)[source]¶
Bases:
Mechanism
Implements auctions in the LLG setting with 3 bidders and 2 goods.
Here, bidders do submit full bundle (XOR) bids. For this specific LLG domain see (Beck and Ott 2013).
Item dim 0 corresponds to item A, dim 1 to item B and dim 2 to the bundle of both.
- class bnelearn.mechanism.auctions_combinatorial.LLLLGGAuction(rule='first_price', core_solver='NoCore', parallel: int = 1, cuda: bool = True)[source]¶
Bases:
Mechanism
Inspired by implementation of Seuken Paper (Bosshard et al. (2019), https://arxiv.org/abs/1812.01955). Hard coded possible solutions for faster batch computations.
- Args:
rule: pricing rule core_solver: which solver to use, only relevant if pricing rule is a core rule parallel: number of processors for parallelization in gurobi (only)
- class bnelearn.mechanism.auctions_combinatorial.LLLLRRGAuction(rule='first_price', core_solver='NoCore', parallel: int = 1, cuda: bool = True)[source]¶
Bases:
LLLLGGAuction
Extended LLLLGG Auction with an additional ‘superglobal’ bider. Implementation is identical to LLLLGG except we overwrite some settings in the constructor.
bnelearn.mechanism.auctions_multiunit module¶
Auction mechanism for multi-unit auctions (where objects are homogeneous).
- class bnelearn.mechanism.auctions_multiunit.FPSBSplitAwardAuction(cuda: bool = True, smoothing_temperature: Optional[float] = None)[source]¶
Bases:
MultiUnitAuction
First-price sealed-bid split-award auction: Multiple agents bidding for either 100% of the share or 50%.
We define a bids as
torch.Tensor
with dimensions (*batch_sizes, n_players, n_bids=2), where the first bid is for the 50% share and the second for the 100% share.- run(bids: Tensor) Tuple[Tensor, Tensor] [source]¶
Performs a batch of split-award auction rounds.
- Args:
- bids: torch.Tensor
of bids with dimensions
(*batch_sizes, n_players, n_items=2)
; first entry of n_items dim corresponds to bid for 50% lot, second entry to bid for 100% lot, etc.
- Returns:
- (allocation, payments): Tuple[torch.Tensor, torch.Tensor]
- allocation: tensor of dimension
(*n_batches x n_players x 2)
, 1 indicating item is allocated to corresponding player in that batch, 0 otherwise.
- payments: tensor of dimension
(*n_batches x n_players)
; total payment from player to auctioneer for her allocation in that batch.
- allocation: tensor of dimension
- class bnelearn.mechanism.auctions_multiunit.MultiUnitAuction(cuda: bool = True, smoothing_temperature: Optional[float] = None)[source]¶
Bases:
Mechanism
Class for multi-unit auctions where multiple identical items (so called units) are for sale. Agents thus don’t care about winning item no. x or no. y, as they’re homogeneous.
- class bnelearn.mechanism.auctions_multiunit.MultiUnitDiscriminatoryAuction(cuda: bool = True, smoothing_temperature: Optional[float] = None)[source]¶
Bases:
MultiUnitAuction
Multi item discriminatory auction. Units are allocated to the highest n_item bids, winners pay as bid.
Bids of each bidder must be in decreasing order, otherwise the mechanism does not accept these bids and allocates no units to this bidder.
- run(bids: Tensor) Tuple[Tensor, Tensor] [source]¶
Runs a (batch of) multi item discriminatory auction(s). Invalid bids (i.e. in increasing order) will be ignored (-> no allocation to that bidder), s.t. the bidder might be able to “learn” the right behavior.
- Args:
- bids: torch.Tensor
of bids with dimensions (*batch_sizes, n_players, n_items); first entry of n_items dim corresponds to bid of first unit, second entry to bid of second unit, etc.
- Returns:
- (allocation, payments): Tuple[torch.Tensor, torch.Tensor]
- allocation: tensor of dimension (n_batches x n_players x
n_items), 1 indicating item is allocated to corresponding player in that batch, 0 otherwise.
- payments: tensor of dimension (n_batches x n_players);
total payment from player to auctioneer for her allocation in that batch.
- class bnelearn.mechanism.auctions_multiunit.MultiUnitUniformPriceAuction(cuda: bool = True, smoothing_temperature: Optional[float] = None)[source]¶
Bases:
MultiUnitAuction
In a uniform-price auction, all units are sold at a “market-clearing” price such that the total amount demanded is equal to the total amount supplied. We adopt the rule that the market-clearing price is the same as the highest losing bid.
Bids of each bidder must be in decreasing order, otherwise the mechanism does not accept these bids and allocates no units to this bidder.
- run(bids: Tensor) Tuple[Tensor, Tensor] [source]¶
Runs a (batch of) Multi Unit Uniform-Price Auction(s). Invalid bids (i.e. in increasing order) will be ignored (-> no allocation to that bidder), s.t. the bidder might be able to “learn” the right behavior.
- Args:
- bids: torch.Tensor
of bids with dimensions (*batch_sizes, n_players, n_items); first entry of n_items dim corresponds to bid of first unit, second entry to bid of second unit, etc.
- Returns:
- (allocation, payments): Tuple[torch.Tensor, torch.Tensor]
- allocation: tensor of dimension (n_batches x n_players x
n_items), 1 indicating item is allocated to corresponding player in that batch, 0 otherwise.
- payments: tensor of dimension (n_batches x n_players);
total payment from player to auctioneer for her allocation in that batch.
- class bnelearn.mechanism.auctions_multiunit.MultiUnitVickreyAuction(cuda: bool = True, smoothing_temperature: Optional[float] = None)[source]¶
Bases:
MultiUnitAuction
In a Vickrey auction, a bidder who wins k units pays the k highest losing bids of the other bidders.
Bids of each bidder must be in decreasing order, otherwise the mechanism does not accept these bids and allocates no units to this bidder.
- run(bids: Tensor) Tuple[Tensor, Tensor] [source]¶
Runs a (batch of) Multi Unit Vickrey Auction(s). Invalid bids (i.e. in increasing order) will be ignored (-> no allocation to that bidder), s.t. the bidder might be able to “learn” the right behavior.
- Args:
- bids: torch.Tensor
of bids with dimensions (*batch_sizes, n_players, n_items); first entry of n_items dim corresponds to bid of first unit, second entry to bid of second unit, etc.
- Returns:
- (allocation, payments): Tuple[torch.Tensor, torch.Tensor]
- allocation: tensor of dimension (n_batches x n_players x
n_items), 1 indicating item is allocated to corresponding player in that batch, 0 otherwise.
- payments: tensor of dimension (n_batches x n_players);
total payment from player to auctioneer for her allocation in that batch.
bnelearn.mechanism.auctions_single_item module¶
- class bnelearn.mechanism.auctions_single_item.AllPayAuction(cuda: bool)[source]¶
Bases:
Mechanism
- run(bids: Tensor) Tuple[Tensor, Tensor] [source]¶
Runs a (batch of) All-Pay Auctions.
This function is meant for single-item auctions. If a bid tensor for multiple items is submitted, each item is auctioned independently of one another.
Parameters¶
- bids: torch.Tensor
of bids with dimensions (*batch_sizes, n_players, n_items)
Returns¶
- (allocation, payments): Tuple[torch.Tensor, torch.Tensor]
- class bnelearn.mechanism.auctions_single_item.FirstPriceSealedBidAuction(**kwargs)[source]¶
Bases:
Mechanism
First Price Sealed Bid auction
- run(bids: Tensor, smooth_market: bool = False) Tuple[Tensor, Tensor] [source]¶
Runs a (batch of) First Price Sealed Bid Auction.
This function is meant for single-item auctions. If a bid tensor for multiple items is submitted, each item is auctioned independently of one another.
Parameters¶
- bids: torch.Tensor
of bids with dimensions (*batch_sizes, n_players, n_items)
Returns¶
- (allocation, payments): Tuple[torch.Tensor, torch.Tensor]
- class bnelearn.mechanism.auctions_single_item.ThirdPriceSealedBidAuction(cuda: bool = True, smoothing_temperature: Optional[float] = None)[source]¶
Bases:
Mechanism
- run(bids: Tensor) Tuple[Tensor, Tensor] [source]¶
Runs a (batch of) Third Price Sealed Bid Auctions.
This function is meant for single-item auctions. If a bid tensor for multiple items is submitted, each item is auctioned independently of one another.
Parameters¶
- bids: torch.Tensor
of bids with dimensions (batch_size, n_players, n_items)
Returns¶
- (allocation, payments): Tuple[torch.Tensor, torch.Tensor]
- allocation: tensor of dimension (n_batches x n_players x n_items),
1 indicating item is allocated to corresponding player in that batch, 0 otherwise
- payments: tensor of dimension (n_batches x n_players)
Total payment from player to auctioneer for her allocation in that batch.
- class bnelearn.mechanism.auctions_single_item.VickreyAuction(random_tie_break: bool = False, **kwargs)[source]¶
Bases:
Mechanism
Vickrey / Second Price Sealed Bid Auctions
- run(bids: Tensor, smooth_market: bool = False) Tuple[Tensor, Tensor] [source]¶
Runs a (batch of) Vickrey/Second Price Sealed Bid Auctions.
This function is meant for single-item auctions. If a bid tensor for multiple items is submitted, each item is auctioned independently of one another.
Parameters¶
- bids: torch.Tensor
of bids with dimensions (batch_size, n_players, n_items)
- smooth_market: Smoothens allocations and payments s.t. the ex-post
utility is continuous again. This introduces a bias though. PG then is applicable.
Returns¶
- (allocation, payments): Tuple[torch.Tensor, torch.Tensor]
- allocation: tensor of dimension (n_batches x n_players x n_items),
1 indicating item is allocated to corresponding player in that batch, 0 otherwise
- payments: tensor of dimension (n_batches x n_players)
Total payment from player to auctioneer for her allocation in that batch.
bnelearn.mechanism.auctions_single_player module¶
- class bnelearn.mechanism.auctions_single_player.StaticFunctionMechanism(cuda: bool = True, smoothing_temperature: Optional[float] = None)[source]¶
Bases:
Mechanism
A static mechanism that can be used for testing purposes, in order to test functionality/efficiency of optimizers without introducing additional stochasticity from multi-player learning dynamics. This function more straightforward than the Static Mechanism above, which has stochasticity similar to an auction.
Instead, this class returns a straight up function, designed such that vanilla PG will also work on it.
Here, the player gets the item with probability 0.5 and pays (5-b)², i.e. it’s optimal to always bid 5. The expected utility in optimal strategy is thus 2.5.
- class bnelearn.mechanism.auctions_single_player.StaticMechanism(cuda: bool = True, smoothing_temperature: Optional[float] = None)[source]¶
Bases:
Mechanism
A static mechanism that can be used for testing purposes, in order to test functionality/efficiency of optimizers without introducing additional stochasticity from multi-player learning dynamics.
In this ‘single-player single-item’ setting, items are allocated with probability bid/10, payments are always given by b²/20, even when the item is not allocated. The expected payoff from this mechanism is thus b/10 * v - 0.05b², The optimal strategy fo an agent with quasilinear utility is given by bidding truthfully.
bnelearn.mechanism.contests_single_item module¶
- class bnelearn.mechanism.contests_single_item.CrowdsourcingContest(cuda: bool = True)[source]¶
Bases:
Mechanism
Crowdsourcing Contest
- run(bids: Tensor) Tuple[Tensor, Tensor] [source]¶
Runs a (batch of) Crowdsourcing Contests.
If a effort tensor for multiple items is submitted, each item is auctioned independently of one another.
Parameters¶
- efforts: torch.Tensor
of efforts with dimensions (*batch_sizes, n_players, n_items)
Returns¶
- (allocation, payments): Tuple[torch.Tensor, torch.Tensor]
- class bnelearn.mechanism.contests_single_item.TullockContest(impact_function, cuda: bool = True)[source]¶
Bases:
Mechanism
Tullock Contest
- run(bids: Tensor) Tuple[Tensor, Tensor] [source]¶
Runs a (batch of) Tullock Contests.
This function is meant for single-item contests. If a effort tensor for multiple items is submitted, each item is auctioned independently of one another.
Note that if multiple contestants submit the highest effort, we choose the first one.
Parameters¶
- bids: torch.Tensor
of efforts with dimensions (*batch_sizes, n_players, n_items)
Returns¶
- (winning_probs, payments): Tuple[torch.Tensor, torch.Tensor]
bnelearn.mechanism.data module¶
This module contains static data about all possible solutions in the LLG and LLLLGG combinatorial auctions, which may constitute efficient allocations.
- class bnelearn.mechanism.data.CombinatorialAuctionData[source]¶
Bases:
ABC
Wraper class to represent static data of a large combinatorial auction.
- classmethod efficient_allocations_dense(device='cpu') Tensor [source]¶
Returns the possible efficient allocations as a dense tensor
- classmethod legal_allocations_dense(device='cpu') Tensor [source]¶
returns a dense torch tensor of all possible legal allocations on the desired device. Output shape: n_legal_allocations x n_bundles
- classmethod legal_allocations_sparse(device='cpu') Tensor [source]¶
returns the sparse index representation of legal allocations as a torch.Tensor.
- abstract class property n_bundles: int¶
- abstract class property n_legal_allocations: int¶
- class bnelearn.mechanism.data.LLGData[source]¶
Bases:
object
Contains static data about legal allocations in the LLG setting.
- bundles = [[0], [1], [0, 1]]¶
- legal_allocations_dense = [[0, 0, 1, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 1, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 1, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 1, 0], [0, 1, 0, 1, 0, 0, 0, 0, 0], [0, 0, 0, 1, 1, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0, 0, 1, 0], [0, 1, 0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 1, 0, 1, 0, 0], [0, 0, 0, 0, 0, 0, 1, 1, 0]]¶
- legal_allocations_sparse = [[0, 0], [1, 1], [2, 2], [3, 3], [4, 4], [5, 5], [6, 6], [7, 7], [8, 8], [9, 0], [9, 4], [10, 1], [10, 3], [11, 0], [11, 1], [12, 0], [12, 7], [13, 1], [13, 6], [14, 3], [14, 4], [15, 3], [15, 7], [16, 4], [16, 6], [17, 6], [17, 7]]¶
- class bnelearn.mechanism.data.LLLLGGData[source]¶
Bases:
CombinatorialAuctionData
Static data about legal and possibly efficient allocations in the LLLLGG setting. For details about the representation, see Bosshard et al. (2019), https://arxiv.org/abs/1812.01955.
- efficient_allocations_semisparse: List[List[int]] = [[0, 2, 4, 6], [1, 3, 5, 7], [4, 6, 8], [0, 2, 9], [0, 6, 10], [2, 4, 11], [5, 8], [1, 9], [7, 10], [3, 11], [0, 2, 5], [2, 4, 7], [1, 4, 6], [0, 3, 6], [0, 3, 5], [2, 5, 7], [1, 3, 6], [1, 4, 7]]¶
- n_bundles = 12¶
- n_legal_allocations = 66¶
- class bnelearn.mechanism.data.LLLLRRGData[source]¶
Bases:
CombinatorialAuctionData
Static data about legal and possibly efficient allocations in the LLLLRRG setting. This extends the LLLLGG setting by adding a 7th, “superglobal” player, who is interested in the bundle of all 8 items.
In this setting, we’ll call the new player ‘global’, and the players interested in 4-item-bundles (R in LLLLRRG, G in LLLLGG) ‘regional’.
- efficient_allocations_semisparse = [[0, 2, 4, 6], [1, 3, 5, 7], [4, 6, 8], [0, 2, 9], [0, 6, 10], [2, 4, 11], [5, 8], [1, 9], [7, 10], [3, 11], [0, 2, 5], [2, 4, 7], [1, 4, 6], [0, 3, 6], [0, 3, 5], [2, 5, 7], [1, 3, 6], [1, 4, 7], 12]¶
- n_bundles = 14¶
- n_legal_allocations = 67¶
bnelearn.mechanism.matrix_games module¶
Matrix Games
- class bnelearn.mechanism.matrix_games.BattleOfTheSexes(**kwargs)[source]¶
Bases:
MatrixGame
Two player, two action Battle of the Sexes game
- class bnelearn.mechanism.matrix_games.BattleOfTheSexesMod(**kwargs)[source]¶
Bases:
MatrixGame
Modified Battle of the Sexes game
- class bnelearn.mechanism.matrix_games.JordanGame(**kwargs)[source]¶
Bases:
MatrixGame
Jordan Anticoordination game (1993), FP does not converge. 3P version of Shapley fashion game: Player Actions: (Left, Right) P1 wants to be different from P2 P2 wants to be different from P3 P3 wants to be different from P1
- class bnelearn.mechanism.matrix_games.MatchingPennies(**kwargs)[source]¶
Bases:
MatrixGame
Two Player, two action Matching Pennies / anticoordination game
- class bnelearn.mechanism.matrix_games.MatrixGame(n_players: int, outcomes: Tensor, cuda: bool = True, names: Optional[dict] = None, validate_inputs: bool = True)[source]¶
Bases:
Game
A complete information Matrix game.
TODO: missing documentation
- calculate_expected_action_payoffs(strategy_profile, player_position)[source]¶
Calculates the expected utility for a player under a mixed opponent strategy
- Args:
- strategy_profile: List of action-probability-vectors for each player.
Player i’s strategy must be supplied but is ignored.
player_position: player of interest
- Returns:
expected payoff per action of player i (tensor of dimension (1 x n_actions[i])
- play(action_profile)[source]¶
Plays the game for a given action_profile.
Parameters¶
- action_profile: torch.Tensor
Shape: (batch_size, n_players, n_items) n_items should be 1 for now. (This might change in the future to represent information sets!) Actions should be integer indices. #TODO: Ipmlement that they can also be action names!
Mixed strategies are NOT allowed as input, sampling should happen in the player class.
Returns¶
- (allocation, payments): Tuple[torch.Tensor, torch.Tensor]
- allocation: tensor of dimension (n_batches x n_players x n_items),
In this setting, there’s nothing to be allocated, so it will be all zeroes.
- payments: tensor of dimension (n_batches x n_players)
Negative outcome/utility for each player.
- play_mixed(strategy_profile: List[Tensor], validate: Optional[bool] = None)[source]¶
Plays the game with mixed strategies, returning expectation of outcomes.
This version does NOT support batches or multiple items, as (1) batches do not make sense in this setting since we are already returning expectations.
Parameters¶
- strategy_profile: List[torch.Tensor]. A list of strategies for each player.
Each element i should be a 1-dimensional torch tensor of length n_actions_pi with entries j = P(player i plays action j)
- validate: bool. Whether to validate inputs. Defaults to setting in game class.
(Validation overhead is ~100%, so you might want to turn this off in settings with many many iterations)
Returns¶
- (allocation, payments): Tuple[torch.Tensor, torch.Tensor]
allocation: empty tensor of dimension (0) –> not used in this game payments: tensor of dimension (n_players)
Negative expected outcome/utility for each player.
- class bnelearn.mechanism.matrix_games.PaulTestGame(**kwargs)[source]¶
Bases:
MatrixGame
A 3-p game without many symmetries used for testing n-player tensor implementations. Payoff: [M,R,C]
- class bnelearn.mechanism.matrix_games.PrisonersDilemma(**kwargs)[source]¶
Bases:
MatrixGame
Two player, two action Prisoner’s Dilemma game. Has a unique pure Nash equilibrium in ap [1,1]
- class bnelearn.mechanism.matrix_games.RockPaperScissors(**kwargs)[source]¶
Bases:
MatrixGame
2 player, 3 action game rock paper scissors
bnelearn.mechanism.mechanism module¶
This module implements games such as matrix games and auctions.
- class bnelearn.mechanism.mechanism.Game(cuda: bool = True)[source]¶
Bases:
ABC
Base class for any kind of games
- class bnelearn.mechanism.mechanism.Mechanism(cuda: bool = True, smoothing_temperature: Optional[float] = None)[source]¶
Bases:
Game
,ABC
Auction Mechanism - Interpreted as a Bayesian game. A Mechanism collects bids from all players, then allocates available items as well as payments for each of the players.
Module contents¶
bnelearn.sampler package¶
Submodules¶
bnelearn.sampler.base module¶
This class provides primitives to implement samplers that support drawing of valuation and observation profiles for a set of players.
- class bnelearn.sampler.base.CompositeValuationObservationSampler(n_players: int, valuation_size: int, observation_size: int, subgroup_samplers: List[ValuationObservationSampler], default_batch_size=1, default_device=None)[source]¶
Bases:
ValuationObservationSampler
A class representing composite prior distributions that are made up of several groups of bidders, each of which can be represented by an atomic ValuationObservationSampler, and which are independent between-group (but not necessarily within-group).
Limitation: The current implementation requires that all players nevertheless have the same valuation_size.
- draw_conditional_profiles(conditioned_player: int, conditioned_observation: Tensor, inner_batch_size: int, device: Optional[Union[device, str, int]] = None) Tuple[Tensor, Tensor] [source]¶
Draws and returns batches conditional valuation and corresponding observation profile. For each entry of conditioned_observation, inner_batch_size samples will be drawn!
Note that here, we are returning full profiles instead (including conditioned_player’s observation and others’ valuations.)
- Args:
- conditioned_player: int
Index of the player whose observation we are conditioning on.
- conditioned_observation: torch.Tensor (*outer_batch_sizes (implicit), observation_size)
A batch of/batches of observations of player conditioned_player.
- Kwargs:
batch_size (optional): int, the “inner”batch_size to draw - i.e. how many conditional samples to draw for each provided conditional_observation. If none provided, will use self.default_batch_size of the class.
- Returns:
- valuations: torch.Tensor (batch_size x n_players x valuation_size):
a conditional valuation profile
- observations: torch.Tensor (*outer_batch_sizes, inner_batch_size, n_players, observation_size):
a corresponding conditional observation profile. observations[…,conditioned_observation,:] will be equal to conditioned_observation repeated batch_size times
- draw_profiles(batch_sizes: Optional[int] = None, device=None) Tuple[Tensor, Tensor] [source]¶
Draws and returns a batch of valuation and observation profiles.
- Kwargs:
batch_sizes (optional): List[int], the batch_size to draw. If none provided, self.default_batch_size will be used. device (optional): torch.cuda.Device, the device to draw profiles on
- Returns:
valuations: torch.Tensor (*batch_sizes x n_players x valuation_size): a valuation profile observations: torch.Tensor (*batch_sizes x n_players x observation_size): an observation profile
- class bnelearn.sampler.base.FlushedWrappedSampler(base_sampler: ValuationObservationSampler, flush_val_dims: int = 1, flush_obs_dims: int = 1)[source]¶
Bases:
ValuationObservationSampler
A sampler that relies on a base sampler but flushes the last valuation and observations dimensions with zeros.
This is useful when some players have lower observation / valuation size than others.
Note on implementation: an alternative would be using a lower-dimensional base sampler and then adding extra zeroes. We instead go this route of overwriting unnecessary values because the incurred cost of sampling too many values will be cheaper in most cases compared to ‘growing’ tensors after the fact.
- draw_conditional_profiles(conditioned_player: int, conditioned_observation: Tensor, inner_batch_size: int, device: Optional[Union[device, str, int]] = None) Tuple[Tensor, Tensor] [source]¶
Draws and returns batches conditional valuation and corresponding observation profile. For each entry of conditioned_observation, batch_size samples will be drawn!
Note that here, we are returning full profiles instead (including conditioned_player’s observation and others’ valuations.)
- Args:
- conditioned_player: int
Index of the player whose observation we are conditioning on.
- conditioned_observation: torch.Tensor (*outer_batch_sizes (implicit), observation_size)
A (batch of) observations of player conditioned_player.
- Kwargs:
batch_size (optional): int, the “inner”batch_size to draw - i.e. how many conditional samples to draw for each provided conditional_observation. If none provided, will use self.default_batch_size of the class.
- Returns:
- valuations: torch.Tensor (outer_batch_size, inner_batch_size, n_players, valuation_size):
a conditional valuation profile
- observations: torch.Tensor (*`outer_batch_size`s, inner_batch_size, n_players, observation_size):
a corresponding conditional observation profile. observations[:,conditioned_observation,:] will be equal to conditioned_observation repeated batch_size times
- draw_profiles(batch_sizes: Optional[Union[int, List[int]]] = None, device=None) Tuple[Tensor, Tensor] [source]¶
Draws and returns a batch of valuation and observation profiles.
- Kwargs:
batch_sizes (optional): List[int], the batch_sizes to draw. If none provided, [self.default_batch_size] will be used. device (optional): torch.cuda.Device, the device to draw profiles on
- Returns:
valuations: torch.Tensor (*batch_sizes x n_players x valuation_size): a valuation profile observations: torch.Tensor (*batch_sizes x n_players x observation_size): an observation profile
- class bnelearn.sampler.base.IPVSampler(n_players: int, valuation_size: int, support_bounds, default_batch_size: int = 1, default_device: Optional[Union[device, str, int]] = None)[source]¶
Bases:
PVSampler
,ABC
A sampler in Independent Private Value Settings.
NOTE: We will only use this class as an interface to perform quick checks for IPV (e.g. in FlushedWrappedSampler below). Implementation is left to subclasses.
See the module .samplers_ipv for examples.
- class bnelearn.sampler.base.PVSampler(n_players: int, valuation_size: int, support_bounds, default_batch_size: int = 1, default_device: Optional[Union[device, str, int]] = None)[source]¶
Bases:
ValuationObservationSampler
,ABC
A sampler for Private Value settings, i.e. when observations and valuations are identical.
- draw_profiles(batch_sizes: Optional[int] = None, device: Optional[Union[device, str, int]] = None) Tuple[Tensor, Tensor] [source]¶
Draws and returns a batch of valuation and observation profiles.
- Kwargs:
batch_sizes (optional): List[int], the batch_sizes to draw. If none provided, [self.default_batch_size] will be used. device (optional): torch.cuda.Device, the device to draw profiles on
- Returns:
valuations: torch.Tensor (*batch_sizes x n_players x valuation_size): a valuation profile observations: torch.Tensor (*batch_sizes x n_players x observation_size): an observation profile
- class bnelearn.sampler.base.ValuationObservationSampler(n_players, valuation_size, observation_size, support_bounds, default_batch_size=1, default_device=None)[source]¶
Bases:
ABC
Provides functionality to draw valuation and observation profiles.
- abstract draw_conditional_profiles(conditioned_player: int, conditioned_observation: Tensor, inner_batch_size: int, device: Optional[Union[device, str, int]] = None) Tuple[Tensor, Tensor] [source]¶
Draws and returns batches conditional valuation and corresponding observation profile. For each entry of conditioned_observation, batch_size samples will be drawn!
Note that here, we are returning full profiles instead (including conditioned_player’s observation and others’ valuations.)
- Args:
- conditioned_player: int
Index of the player whose observation we are conditioning on.
- conditioned_observation: torch.Tensor (*outer_batch_sizes (implicit), observation_size)
A (batch of) observations of player conditioned_player.
- Kwargs:
batch_size (optional): int, the “inner”batch_size to draw - i.e. how many conditional samples to draw for each provided conditional_observation. If none provided, will use self.default_batch_size of the class.
- Returns:
- valuations: torch.Tensor (outer_batch_size, inner_batch_size, n_players, valuation_size):
a conditional valuation profile
- observations: torch.Tensor (*`outer_batch_size`s, inner_batch_size, n_players, observation_size):
a corresponding conditional observation profile. observations[:,conditioned_observation,:] will be equal to conditioned_observation repeated batch_size times
- abstract draw_profiles(batch_sizes: Optional[Union[int, List[int]]] = None, device=None) Tuple[Tensor, Tensor] [source]¶
Draws and returns a batch of valuation and observation profiles.
- Kwargs:
batch_sizes (optional): List[int], the batch_sizes to draw. If none provided, [self.default_batch_size] will be used. device (optional): torch.cuda.Device, the device to draw profiles on
- Returns:
valuations: torch.Tensor (*batch_sizes x n_players x valuation_size): a valuation profile observations: torch.Tensor (*batch_sizes x n_players x observation_size): an observation profile
- generate_action_grid(player_position: int, minimum_number_of_points: int, dtype=torch.float32, device=None) Tensor [source]¶
As the grid is also used for finding best responses, some samplers need extensive grids that sample a broader area. (E.g. when a bidder with high valuations massively shads her bids.)
- generate_cell_partition(player_position: int, grid_size: int, dtype=torch.float32, device=None)[source]¶
Generate a rectangular grid partition of the valuation/observation prior and return cells with their vertices.
- generate_reduced_grid(player_position: int, minimum_number_of_points: int, dtype=torch.float32, device=None) Tensor [source]¶
For some samplers, the action dimension is smaller and the grid can be reduced to that lower dimension.
- generate_valuation_grid(player_position: int, minimum_number_of_points: int, dtype=torch.float32, device=None, support_bounds: Optional[Tensor] = None, return_mesh: bool = False) Tensor [source]¶
Generates an evenly spaced grid of (approximately and at least) minimum_number_of_points valuations covering the support of the valuation space for the given player. These are meant as rational actions for the player to evaluate, e.g. in the util_loss estimator.
The default reference implementation returns a rectangular grid on [0, upper_bound] x valuation_size.
bnelearn.sampler.samplers_ipv module¶
This module implements samplers for independent-private value auction settings.
Note that all samplers in this class should implement the IPVSampler interface from .base. Elsewhere in the implementation, we use instancechecks against IPVSampler in order to use functionality that is only available in independent settings, e.g. when drawing samples from conditional distributions.
- class bnelearn.sampler.samplers_ipv.BetaSymmetricIPVSampler(alpha: float, beta: float, n_players: int, valuation_size: int, default_batch_size: int, default_device: Optional[Union[device, str, int]] = None)[source]¶
Bases:
SymmetricIPVSampler
An IPV sampler with symmetric Beta priors.
- class bnelearn.sampler.samplers_ipv.FixedManualIPVSampler(valuation_tensor: Tensor)[source]¶
Bases:
IPVSampler
For testing purposes: A sampler that returns a fixed tensor as valuations/observations.
- class bnelearn.sampler.samplers_ipv.GaussianSymmetricIPVSampler(mean, stddev, n_players, valuation_size, default_batch_size, default_device: Optional[Union[device, str, int]] = None)[source]¶
Bases:
SymmetricIPVSampler
An IPV sampler with symmetric Gaussian priors.
- class bnelearn.sampler.samplers_ipv.MultiUnitValuationObservationSampler(n_players: int, n_items: int = 1, max_demand: Optional[int] = None, constant_marginal_values: bool = False, u_lo: float = 0.0, u_hi: float = 1.0, default_batch_size: int = 1, default_device=None)[source]¶
Bases:
UniformSymmetricIPVSampler
Sampler for Multi-Unit, private value settings. Sampler for valuations and signals in Multi-Unit Auctions, following Krishna, Chapter 13.
These are symmetric private value settings, where
valuations are descending along the valuation_size dimension and represent the marginal utility of winning an additional item.
bidders may be limited to be interested in at most a certain number of items.
- generate_cell_partition(player_position: int, grid_size: int, dtype=torch.float32, device=None)[source]¶
Generate a rectangular grid partition of the valuation/observation prior and return cells with their vertices.
- generate_valuation_grid(player_position: int, minimum_number_of_points: int, dtype=torch.float32, device=None, support_bounds: Optional[Tensor] = None, return_mesh: bool = False) Tensor [source]¶
Generates an evenly spaced grid of (approximately and at least) minimum_number_of_points valuations covering the support of the valuation space for the given player. These are meant as rational actions for the player to evaluate, e.g. in the util_loss estimator.
The default reference implementation returns a rectangular grid on [0, upper_bound] x valuation_size.
- class bnelearn.sampler.samplers_ipv.SplitAwardValuationObservationSampler(efficiency_parameter: float, **kwargs)[source]¶
Bases:
UniformSymmetricIPVSampler
Sampler for Split-Award, private value settings. Here bidders have two valuations of which one is a linear combination of the other.
- generate_action_grid(player_position: int, minimum_number_of_points: int, dtype=torch.float32, device=None) Tensor [source]¶
From zero to some maximal value. Here, unlike in the other methods, the two outputs must not be linearly dependent.
- generate_valuation_grid(player_position: int, minimum_number_of_points: int, dtype=torch.float32, device=None, support_bounds: Optional[Tensor] = None, return_mesh: bool = False) Tensor [source]¶
Generates an evenly spaced grid of (approximately and at least) minimum_number_of_points valuations covering the support of the valuation space for the given player. These are meant as rational actions for the player to evaluate, e.g. in the util_loss estimator.
The default reference implementation returns a rectangular grid on [0, upper_bound] x valuation_size.
- class bnelearn.sampler.samplers_ipv.SymmetricIPVSampler(distribution: Distribution, n_players: int, valuation_size: int = 1, default_batch_size: int = 1, default_device: Optional[Union[device, str, int]] = None)[source]¶
Bases:
IPVSampler
A Valuation Oracle that draws valuations independently and symmetrically for all players and each entry of their valuation vector according to a specified distribution.
This base class works with all torch.distributions but requires sampling on cpu then moving to the device. When using cuda, use the faster, distribution-specific subclasses instead where provided.
- UPPER_BOUND_QUARTILE_IF_UNBOUNDED = 0.999¶
- draw_conditional_profiles(conditioned_player: int, conditioned_observation: Tensor, inner_batch_size: int, device: Optional[Union[device, str, int]] = None) Tuple[Tensor, Tensor] [source]¶
Draws and returns batches conditional valuation and corresponding observation profile. For each entry of conditioned_observation, batch_size samples will be drawn!
Note that here, we are returning full profiles instead (including conditioned_player’s observation and others’ valuations.)
- Args:
- conditioned_player: int
Index of the player whose observation we are conditioning on.
- conditioned_observation: torch.Tensor (*outer_batch_sizes (implicit), observation_size)
A (batch of) observations of player conditioned_player.
- Kwargs:
batch_size (optional): int, the “inner”batch_size to draw - i.e. how many conditional samples to draw for each provided conditional_observation. If none provided, will use self.default_batch_size of the class.
- Returns:
- valuations: torch.Tensor (outer_batch_size, inner_batch_size, n_players, valuation_size):
a conditional valuation profile
- observations: torch.Tensor (*`outer_batch_size`s, inner_batch_size, n_players, observation_size):
a corresponding conditional observation profile. observations[:,conditioned_observation,:] will be equal to conditioned_observation repeated batch_size times
- class bnelearn.sampler.samplers_ipv.UniformSymmetricIPVSampler(lo, hi, n_players, valuation_size, default_batch_size, default_device: Optional[Union[device, str, int]] = None)[source]¶
Bases:
SymmetricIPVSampler
An IPV sampler with symmetric Uniform priors.
- default_batch_size: int¶
- default_device: Optional[Union[device, str, int]]¶
- n_players: int¶
- observation_size: int¶
- support_bounds: FloatTensor¶
- valuation_size: int¶
bnelearn.sampler.samplers_non_pv module¶
This module implements samplers that do not adhere to the private values setting.
- class bnelearn.sampler.samplers_non_pv.AffiliatedValuationObservationSampler(n_players: int, valuation_size: int = 1, u_lo: float = 0.0, u_hi: float = 1.0, default_batch_size: int = 1, default_device=None)[source]¶
Bases:
ValuationObservationSampler
The ‘Affiliated Values Model’ model. (Krishna 2009, Example 6.2). This is a private values model.
Two bidders have signals
\[\]o_i = z_i + s
and valuations .. math:: v_i = s + (z_1+z_2)/2 = mean_i(o_i)
where z_i and s are i.i.d. standard uniform.
- draw_conditional_profiles(conditioned_player: int, conditioned_observation: Tensor, inner_batch_size: int, device: Optional[Union[device, str, int]] = None) Tuple[Tensor, Tensor] [source]¶
Draws and returns batches conditional valuation and corresponding observation profile. For each entry of conditioned_observation, batch_size samples will be drawn!
Note that here, we are returning full profiles instead (including conditioned_player’s observation and others’ valuations.)
- Args:
- conditioned_player: int
Index of the player whose observation we are conditioning on.
- conditioned_observation: torch.Tensor (*outer_batch_sizes (implicit), observation_size)
A (batch of) observations of player conditioned_player.
- Kwargs:
batch_size (optional): int, the “inner”batch_size to draw - i.e. how many conditional samples to draw for each provided conditional_observation. If none provided, will use self.default_batch_size of the class.
- Returns:
- valuations: torch.Tensor (outer_batch_size, inner_batch_size, n_players, valuation_size):
a conditional valuation profile
- observations: torch.Tensor (*`outer_batch_size`s, inner_batch_size, n_players, observation_size):
a corresponding conditional observation profile. observations[:,conditioned_observation,:] will be equal to conditioned_observation repeated batch_size times
- draw_profiles(batch_sizes: Optional[List[int]] = None, device=None) Tuple[Tensor, Tensor] [source]¶
Draws and returns a batch of valuation and observation profiles.
- Kwargs:
batch_sizes (optional): List[int], the batch_sizes to draw. If none provided, [self.default_batch_size] will be used. device (optional): torch.cuda.Device, the device to draw profiles on
- Returns:
valuations: torch.Tensor (*batch_sizes x n_players x valuation_size): a valuation profile observations: torch.Tensor (*batch_sizes x n_players x observation_size): an observation profile
- class bnelearn.sampler.samplers_non_pv.MineralRightsValuationObservationSampler(n_players: int, valuation_size: int = 1, common_value_lo: float = 0.0, common_value_hi: float = 1.0, default_batch_size: int = 1, default_device=None)[source]¶
Bases:
ValuationObservationSampler
The ‘Mineral Rights’ model is a common value model: There is a uniformly distributed common value of the item(s), each agent’s observation is then uniformly drawn from U[0,2v]. See Kishna (2009), Example 6.1
- draw_conditional_profiles(conditioned_player: int, conditioned_observation: Tensor, inner_batch_size: int, device: Optional[Union[device, str, int]] = None) Tuple[Tensor, Tensor] [source]¶
Draws and returns batches conditional valuation and corresponding observation profile. For each entry of conditioned_observation, batch_size samples will be drawn!
Note that here, we are returning full profiles instead (including conditioned_player’s observation and others’ valuations.)
- Args:
- conditioned_player: int
Index of the player whose observation we are conditioning on.
- conditioned_observation: torch.Tensor (*outer_batch_sizes (implicit), observation_size)
A (batch of) observations of player conditioned_player.
- Kwargs:
batch_size (optional): int, the “inner”batch_size to draw - i.e. how many conditional samples to draw for each provided conditional_observation. If none provided, will use self.default_batch_size of the class.
- Returns:
- valuations: torch.Tensor (outer_batch_size, inner_batch_size, n_players, valuation_size):
a conditional valuation profile
- observations: torch.Tensor (*`outer_batch_size`s, inner_batch_size, n_players, observation_size):
a corresponding conditional observation profile. observations[:,conditioned_observation,:] will be equal to conditioned_observation repeated batch_size times
- draw_profiles(batch_sizes: Optional[List[int]] = None, device=None) Tuple[Tensor, Tensor] [source]¶
Draws and returns a batch of valuation and observation profiles.
- Kwargs:
batch_sizes (optional): List[int], the batch_sizes to draw. If none provided, [self.default_batch_size] will be used. device (optional): torch.cuda.Device, the device to draw profiles on
- Returns:
valuations: torch.Tensor (*batch_sizes x n_players x valuation_size): a valuation profile observations: torch.Tensor (*batch_sizes x n_players x observation_size): an observation profile
Module contents¶
bnelearn.tests package¶
Subpackages¶
bnelearn.tests.test_samplers package¶
Submodules¶
bnelearn.tests.test_samplers.test_affiliated_value module¶
This pytest test file checks whether valuation and observation samplers have the expected behaviour
bnelearn.tests.test_samplers.test_composite_samplers module¶
This pytest test file checks whether valuation and observation samplers have the expected behaviour
bnelearn.tests.test_samplers.test_ipv module¶
This pytest test file checks whether valuation and observation samplers have the expected behaviour
- bnelearn.tests.test_samplers.test_ipv.check_validity(valuation_profile, expected_shape, expected_mean, expected_std, expected_correlation=None)[source]¶
Checks whether a given batch of profiles has expected shape, mean, std and correlation matrix.
- bnelearn.tests.test_samplers.test_ipv.correlation(valuation_profile)[source]¶
Pearson correlation between valuations of bidders.
valuation_profile should be (batch x n_players x 1)
bnelearn.tests.test_samplers.test_mineral_rights module¶
This pytest test file checks whether valuation and observation samplers have the expected behaviour
bnelearn.tests.test_samplers.test_multi_unit module¶
This pytest test file checks whether valuation and observation samplers have the expected behaviour
Module contents¶
Submodules¶
bnelearn.tests.conftest module¶
This module defines pytest fixtures and sets constants to be used in test files.
bnelearn.tests.test_auction_environment module¶
This module tests whether rewards can be calculated correctly in an environment.
bnelearn.tests.test_auction_learning module¶
Test auction learning in symmetric and asymmetric implementations, using a 2p-FPSB setup.
This script tests
whether the loop runs without runtime exceptions for a small number of iterations
whether the model learnt the appropriate bid for the top-range of valuations (this value is expected to be learned _very_ fast as it’s most significant and as such should always be found (up to a certain range) even in a short amount of time)
Further, the script tests whether the utility after 200 iterations is in the expected range, if it isn’t it won’t fail but issue a warning (because this might just be due to stochasticity as it would take a significantly longer test time / more iterations to make sure.)
bnelearn.tests.test_bne_database module¶
Testing correctness of the BNE utilities database.
bnelearn.tests.test_combinatorial_auctions module¶
Testing correctness of LLLLGG combinatorial auction implementations.
bnelearn.tests.test_experiment_serialization module¶
bnelearn.tests.test_learners module¶
This module tests implemented learner in a ‘static’ environment.
- bnelearn.tests.test_learners.strat_to_bidder(strategy, batch_size, player_position=0)[source]¶
creates a bidder from a strategy
- bnelearn.tests.test_learners.test_AESPG_learner_SGD()[source]¶
Tests the standard policy gradient learner in static env. This does not test complete convergence but ‘running in the right direction’.
- bnelearn.tests.test_learners.test_ES_learner_SGD()[source]¶
Tests ES PG learner with SGD optimizer in static environment. This does not test complete convergence but ‘running in the right direction’.
- bnelearn.tests.test_learners.test_PG_learner_SGD()[source]¶
Tests the standard policy gradient learner in static env. This does not test complete convergence but ‘running in the right direction’.
bnelearn.tests.test_llg_auctions module¶
Testing correctness of LLG combinatorial auction implementations.
- bnelearn.tests.test_llg_auctions.run_llg_test(rule, device, expected_payments)[source]¶
Run correctness test for a given llg rule on given device
- bnelearn.tests.test_llg_auctions.test_LLG_first_price()[source]¶
FP should run on CPU and GPU and return expected results.
- bnelearn.tests.test_llg_auctions.test_LLG_full()[source]¶
LLG setting with complete combinatrial (3d) bids.
- bnelearn.tests.test_llg_auctions.test_LLG_nearest_bid()[source]¶
LLG with nearest-bid rule should run on CPU and GPU and return expected results.
- bnelearn.tests.test_llg_auctions.test_LLG_nearest_vcg()[source]¶
LLG with nearest-VCG rule should run on CPU and GPU and return expected results.
bnelearn.tests.test_llllgg_auctions module¶
Testing correctness of LLLLGG combinatorial auction implementations.
- bnelearn.tests.test_llllgg_auctions.run_LLLLGG_test(parallel, rule, device, bids, expected_allocation, expected_payments, solver)[source]¶
Run correctness test for a given LLLLGG rule
bnelearn.tests.test_llllgg_core_solver_comp module¶
Testing for identical results from solvers for the LLLLGG combinatorial auction implementations.
bnelearn.tests.test_market_outcomes module¶
This module tests the calculation of market outcomes.
- bnelearn.tests.test_market_outcomes.run_efficiency_test(experiment_type=<class 'str'>, setting_params=<class 'dict'>, true_efficiency=<class 'float'>)[source]¶
Test the calculation of efficiency for general auction markets
bnelearn.tests.test_matrix_FP module¶
- bnelearn.tests.test_matrix_FP.test_FictitiousPlayStrategy_BoS()[source]¶
initial_beliefs = [None] * 2 #initial_beliefs[0] = torch.tensor([[0.8308,0.5793],[0.4064,0.4113]], device=device) <- converges #initial_beliefs[1] = torch.tensor([[0.2753,0.4043],[0.1596,0.6916]], device=device) <- converges
#initial_beliefs[0] = torch.tensor([[0.5892,0.4108],[0.4970,0.5030]], device=device) #<- converges #initial_beliefs[1] = torch.tensor([[0.4051,0.5949],[0.1875,0.8125]], device=device) #<- converges
#initial_beliefs[0] = torch.tensor([[0.59,0.41],[0.49,0.51]], device=device) #<- converges #initial_beliefs[1] = torch.tensor([[0.41,0.59],[0.19,0.81]], device=device) #<- converges
#initial_beliefs[0] = torch.tensor([[0.59,0.41],[0.49,0.51]], device=device) #<- converges #initial_beliefs[1] = torch.tensor([[0.59,0.41],[0.49,0.51]], device=device) #<- converges
#initial_beliefs[0] = torch.tensor([[0.59,0.41],[0.41,0.59]], device=device) #<- converges #initial_beliefs[1] = torch.tensor([[0.59,0.41],[0.41,0.59]], device=device) #<- converges
#initial_beliefs[0] = torch.tensor([[59.5,40.5],[40.5,59.5]], device=device) #<- converges #initial_beliefs[1] = torch.tensor([[59.5,40.5],[40.5,59.5]], device=device) #<- converges
#initial_beliefs[0] = torch.tensor([[59,41],[49,51]], device=device) #<- doesn’t converge #initial_beliefs[1] = torch.tensor([[41,59],[19,81]], device=device) #<- doens’t converge
#initial_beliefs[0] = torch.tensor([[0.6,0.4],[0.5,0.5]], device=device) #<- doesn’t converge #initial_beliefs[1] = torch.tensor([[0.4,0.6],[0.1875,0.8125]], device=device) #<- doesn’t converge
#initial_beliefs[0] = torch.tensor([[0.6,0.4],[0.5,0.5]], device=device) #<- doesn’t converge #initial_beliefs[1] = torch.tensor([[0.4,0.6],[0.2,0.8]], device=device) #<- doesn’t converge
#initial_beliefs = torch.tensor([[60,41],[41,60]], device=device) #<- doesn’t converge #initial_beliefs[1] = torch.tensor([[60,41],[41,60]], device=device) #<- doesn’t converge
# -> It converges if the init is very close to MNE play for at least one player but not exactly! # -> My hypotheses: it has to be close to cycle. If it is exact, # it is indifferent and takes a random direction, diverging away. # -> $$ The question now is whether we should/have track historical actions with integer!? # -> No. In Fudenberg (1999) - Learning and Equilirbium, p. 389 # they init FP with (1,sqrt(2)), so obviously use float as well.
bnelearn.tests.test_matrix_game_training module¶
Test whether agent training in simple matrix games works.
- bnelearn.tests.test_matrix_game_training.test_prisoners_dilemma_training_separate_models()[source]¶
Tests training in MatrixGameEnvironment with unique models for both players.
Tests training in MatrixGameEnvironment with a shared model between players.
bnelearn.tests.test_matrix_games module¶
- bnelearn.tests.test_matrix_games.test_mixed_strategy_playing_2p()[source]¶
Test in Prisoner’s Dilemma
- bnelearn.tests.test_matrix_games.test_output_correctness_2x3()[source]¶
2 player 3 action game: Rock Paper Scissors
- bnelearn.tests.test_matrix_games.test_output_correctness_3x2()[source]¶
3 player 2 action game: Jordan Anticoordination game.
bnelearn.tests.test_multi_unit_auctions module¶
Testing correctness of auction implementations.
- bnelearn.tests.test_multi_unit_auctions.test_mida_correctness()[source]¶
Test of allocation and payments in MultiUnitDiscriminatoryAuction.
bnelearn.tests.test_reverse_auctions module¶
Testing correctness of reverse auction implementations.
bnelearn.tests.test_single_item_auctions module¶
Testing correctness of auction implementations.
- bnelearn.tests.test_single_item_auctions.test_allpay_correctness()[source]¶
Thirdprice should return correct allocations and payments.
- bnelearn.tests.test_single_item_auctions.test_allpay_illegal_arguments()[source]¶
Illegal bid tensors should cause exceptions
- bnelearn.tests.test_single_item_auctions.test_fpsb_correctness()[source]¶
FPSB should return correct allocations and payments.
- bnelearn.tests.test_single_item_auctions.test_fpsb_illegal_arguments()[source]¶
Illegal bid tensors should cause exceptions
- bnelearn.tests.test_single_item_auctions.test_thirdprice_correctness()[source]¶
Thirdprice should return correct allocations and payments.
bnelearn.tests.test_single_item_contests module¶
Testing correctness of contest implementations.
- bnelearn.tests.test_single_item_contests.impact_function(x)¶
- bnelearn.tests.test_single_item_contests.test_crowdsourcing_correctness()[source]¶
Crowdsourcing Contest should return correct allocations and payments.
- bnelearn.tests.test_single_item_contests.test_crowdsourcing_illegal_arguments()[source]¶
Illegal effort tensors should cause exceptions.
bnelearn.tests.test_strategies_and_bidders module¶
This test file checks whether bidders and strategies have expected behaviour
- bnelearn.tests.test_strategies_and_bidders.test_action_caching_with_manual_observation_change()[source]¶
Manually changing bidder observations should not break action caching logic.
- bnelearn.tests.test_strategies_and_bidders.test_bidder_with_cached_actions()[source]¶
Bidder with action caching should not re-evaluate until valuations have changed.
- bnelearn.tests.test_strategies_and_bidders.test_closure_strategy_basic()[source]¶
Closure Strategy should return expected result
- bnelearn.tests.test_strategies_and_bidders.test_closure_strategy_invalid_input()[source]¶
Invalid closures should raise exception
bnelearn.tests.test_strategies_nn module¶
This test file checks whether NeuralNetStrategy initializations have the correct behavior.
bnelearn.tests.test_util_loss_estimator module¶
Testing correctness of util_loss estimator for a number of settings. Estimates the potential benefit of deviating from the current energy, as:
- param agent:
1
- param bid_profile:
\((batch\_size * n\_player * n\_items)\)
- param bid_i:
\((bid\_size * n\_items)\)
- return:
util_loss_max
- return:
util_loss_expected
bid_i always used as val_i and only using truthful bidding
- bnelearn.tests.test_util_loss_estimator.test_ex_interim_util_loss_estimator_fpsb_bne()[source]¶
Test the util_loss in BNE of fpsb. - ex interim util_loss should be close to zero
bnelearn.tests.test_zzz_experiment_runtime module¶
This file tests the run of experiments at runtime, so simply whether it technically completes the run. It chooses only 2 runs, with 3 epochs but plots and logs every period. Logging and plotting is not written to disc. It considers each implemented experiment with each payment rule. Fo each experiment no model_sharing is tested once. TODO:
Paul: InputLength should become obsolete Stefan: yes! @assigned Paul
Paul: Maybe later: Add bne metric to LLLLGG and test for failure
Stefan: Later: gaussian with fpsb and util_loss
- bnelearn.tests.test_zzz_experiment_runtime.test_local_global_auctions(config, exp_class, known_bne)[source]¶
Module contents¶
bnelearn.util package¶
Submodules¶
bnelearn.util.autograd_hacks module¶
Library for extracting interesting quantites from autograd, see README.md
Not thread-safe because of module-level variables
Author: cybertronai @ https://github.com/cybertronai/autograd-hacks.
Notation: o: number of output classes (exact Hessian), number of Hessian samples (sampled Hessian) n: batch-size do: output dimension (output channels for convolution) di: input dimension (input channels for convolution) Hi: per-example Hessian of matmul, shaped as matrix of [dim, dim], indices have been row-vectorized Hi_bias: per-example Hessian of bias Oh, Ow: output height, output width (convolution) Kh, Kw: kernel height, kernel width (convolution)
Jb: batch output Jacobian of matmul, output sensitivity for example,class pair, [o, n, ….] Jb_bias: as above, but for bias
A, activations: inputs into current layer B, backprops: backprop values (aka Lop aka Jacobian-vector product) observed at current layer
- bnelearn.util.autograd_hacks.add_hooks(model: Module) None [source]¶
Adds hooks to model to save activations and backprop values.
The hooks will 1. save activations into param.activations during forward pass 2. append backprops to params.backprops_list during backward pass.
Call “remove_hooks(model)” to disable this.
- Args:
model:
- bnelearn.util.autograd_hacks.backprop_hess(output: Tensor, hess_type: str) None [source]¶
Call backprop 1 or more times to get values needed for Hessian computation.
- Args:
output: prediction of neural network (ie, input of nn.CrossEntropyLoss()) hess_type: type of Hessian propagation, “CrossEntropy” results in exact Hessian for CrossEntropy
Returns:
- bnelearn.util.autograd_hacks.clear_backprops(model: Module) None [source]¶
Delete layer.backprops_list in every layer.
- bnelearn.util.autograd_hacks.compute_grad1(model: Module, loss_type: str = 'mean') None [source]¶
Compute per-example gradients and save them under ‘param.grad1’. Must be called after loss.backprop()
- Args:
model: loss_type: either “mean” or “sum” depending whether backpropped loss was averaged or summed over batch
- bnelearn.util.autograd_hacks.compute_hess(model: Module) None [source]¶
Save Hessian under param.hess for each param in the model
- bnelearn.util.autograd_hacks.disable_hooks() None [source]¶
Globally disable all hooks installed by this library.
- bnelearn.util.autograd_hacks.is_supported(layer: Module) bool [source]¶
Check if this layer is supported
- bnelearn.util.autograd_hacks.remove_hooks(model: Module) None [source]¶
Remove hooks added by add_hooks(model)
- bnelearn.util.autograd_hacks.symsqrt(a, cond=None, return_rank=False, dtype=torch.float32)[source]¶
Symmetric square root of a positive semi-definite matrix. See https://github.com/pytorch/pytorch/issues/25481
bnelearn.util.distribution_util module¶
Some utilities to work with torch.Distributions.
- bnelearn.util.distribution_util.copy_dist_to_device(dist, device)[source]¶
A quick an dirty workaround to move torch.Distributions from one device to another.
To do so, we return a copy of the original distribution with all its tensor-valued members moved to the desired device.
Note that this will only work for the most basic distributions and will likely fail for complex or composed distribution objects. See https://github.com/pytorch/pytorch/issues/7795 for details.
bnelearn.util.integration module¶
Some utilities to leverage parallel computation of the types of integrals that arise in BNEs.
- bnelearn.util.integration.cumulatively_integrate(f: callable, upper_bounds: tensor, lower_bound: float = 0.0, n_evaluations: int = 64)[source]¶
Integrate the fucntion f on the intervals [[lower_bound, upper_bounds[0], [lower_bound, upper_bounds[1], …] that sahre a common lower bound.
This function sorts the upper bounds, decomposes the integral into those between any two adjacent points in lower_bound, *upper_bounds, calculates each partial integral using pytorch’s trapezoid rule with n_evalautions sampling points per interval, then stichtes the resulting masses together to achieve the desired output. Note that this way, we can use pytorch.trapz in parallel over all domains and integrate directly on cuda, if desired.
- Arguments:
f: callable, function to be integrated. upper_bounds: torch.tensor of shape (batch_size, 1) that specifies the
upper integration bounds.
lower_bound: float that specifies the lower bound of all domains. n_evaluations: int that specifies the number of function evaluations per
indivdidual interval.
- Returns:
integrals: torch.tensor of shape (batch_size, 1).
bnelearn.util.logging module¶
This module contains utilities for logging of experiments
- class bnelearn.util.logging.CustomSummaryWriter(log_dir=None, comment='', purge_step=None, max_queue=10, flush_secs=120, filename_suffix='')[source]¶
Bases:
SummaryWriter
Extends SummaryWriter with two methods:
- a method to add multiple scalars in the way that we intend. The original
SummaryWriter can either add a single scalar at a time or multiple scalars, but in the latter case, multiple runs are created without the option to control these.
- overwriting the the add_hparams method to write hparams without creating
another tensorboard run file
- add_hparams(hparam_dict=None, metric_dict=None, global_step=None)[source]¶
Overides the parent method to prevent the creation of unwanted additional subruns while logging hyperparams, as it is done by the original PyTorch method
- add_metrics_dict(metrics_dict: dict, run_suffices: List[str], global_step=None, walltime=None, group_prefix: Optional[str] = None, metric_tag_mapping: Optional[dict] = None)[source]¶
- Args:
- metric_dict (dict): A dict of metrics. Keys are tag names, values are values.
values can be float, List[float] or Tensor. When List or (nonscalar) tensor, the length must match n_models
- run_suffices (List[str]): if each value in metrics_dict is scalar, doesn’t need to be supplied.
When metrics_dict contains lists/iterables, they must all have the same length which should be equal to the length of run_suffices
global_step (int, optional): The step/iteration at which the metrics are being logged. walltime group_prefix (str, optional): If given each metric name will be prepended with this prefix (and a ‘/’),
which will group tags in tensorboard into categories.
- metric_tag_mapping (dict, optional): A dactionary that provides a mapping between the metrics (keys of metrics_dict)
and the desired tag names in tensorboard. If given, each metric name will be converted to the corresponding tag name. NOTE: bnelearn.util.metrics.MAPPING_METRICS_TAGS contains a standard mapping for common metrics. These already include (metric-specific) prefixes.
- bnelearn.util.logging.export_stepwise_linear_bid(experiment_dir, bidders: List[Bidder], step=0.01)[source]¶
expoerting grid valuations and corresponding bids for usage of verifier.
Args¶
experiment_dir: str, dir where export is going to be saved bidders: List[Bidder], to be evaluated here step: float, step length
Returns¶
to disk: List[csv]
- bnelearn.util.logging.log_git_commit_hash(experiment_dir)[source]¶
Saves the hash of the current git commit into experiment_dir.
- bnelearn.util.logging.print_aggregate_tensorboard_logs(experiment_dir)[source]¶
Prints in a tabular form the aggregate log from all the runs in the current experiment, reads data from the csv file in the experiment directory
- bnelearn.util.logging.print_full_tensorboard_logs(experiment_dir, first_row: int = 0, last_row=None)[source]¶
Prints in a tabular form the full log from all the runs in the current experiment, reads data from a pkl file in the experiment directory :param first_row: the first row to be printed if the full log is used :param last_row: the last row to be printed if the full log is used
- bnelearn.util.logging.process_figure(fig, epoch=None, figure_name='plot', tb_group='eval', tb_writer=None, display=False, output_dir=None, save_png=False, save_svg=False)[source]¶
displays, logs and/or saves a figure
- bnelearn.util.logging.read_bne_utility_database(exp: Experiment)[source]¶
Check if this setting’s BNE has been saved to disk before.
- Args:
exp: Experiment
- Returns:
- db_batch_size: int
sample size of a DB entry if found, else -1
- db_bne_utility: List[n_players]
list of the saved BNE utilites
- bnelearn.util.logging.save_experiment_config(experiment_log_dir, experiment_configuration: ExperimentConfig)[source]¶
Serializes ExperimentConfiguration into a readable JSON file
- Parameters:
experiment_log_dir – full path except for the file name
experiment_configuration – experiment configuration as given by ConfigurationManager
- bnelearn.util.logging.tabulate_tensorboard_logs(experiment_dir, write_aggregate=True, write_detailed=False, write_binary=False)[source]¶
This function reads all tensorboard event log files in subdirectories and converts their content into a single csv file containing info of all runs.
- bnelearn.util.logging.write_bne_utility_database(exp: Experiment, bne_utilities_sampled: list)[source]¶
Write the sampled BNE utilities to disk.
- Args:
exp: Experiment bne_utilities_sampled: list
BNE utilites that are to be writen to disk
bnelearn.util.metrics module¶
This module implements metrics that may be interesting.
- bnelearn.util.metrics.ex_interim_util_loss(env: AuctionEnvironment, player_position: int, agent_observations: Tensor, grid_size: int, opponent_batch_size: Optional[int] = None, grid_best_response: bool = False)[source]¶
Estimates a bidder’s utility loss in the current state of the environment, i.e. the potential benefit of deviating from the current strategy, evaluated at each point of the agent_valuations. Therefore, we calculate
\[\max_{v_i \in V_i} \max_{b_i^* \in A_i} E_{v_{-i}|v_i} [u(v_i, b_i^*, b_{-i}(v_{-i})) - u(v_i, b_i, b_{-i}(v_{-i}))]\]We’re conditioning on the agent’s observation at player_position. That means, types and observations of other players as well as its own type have to be conditioned. As it’s conditioned on the observation, the agent’s action stays the same.
- Args:
env: bnelearn.Environment. player_position: int, position of the player in the environment. grid_size: int, stating the number of alternative actions sampled via
env.agents[player_position].get_valuation_grid(grid_size, True).
opponent_batch_size: int, specifying the sample size for opponents. grid_best_response: bool, whether or not the BRs live on the grid or
possibly come from the actual actions (in case no better response was found on grid).
- Returns:
- utility_loss (torch.Tensor, shape: [batch_size]): the computed
approximate utility loss for for each input observation.
- best_response (torch.Tensor, shape: [batch_size, action_size]):
the best response found for each input observation (This is either a grid point, or the actual action according to the player’s strategy.)
- Remarks:
Relies on availability of draw_conditional_profiles and generate_valuation_grid in the env’s ValuationObservationSampler.
- bnelearn.util.metrics.ex_interim_utility(env: AuctionEnvironment, player_position: int, agent_observations: Tensor, agent_actions: Tensor, opponent_batch_size: int) Tensor [source]¶
Wrapper for ex_interim_utility that makes some computations sequentially if device is OOM.
- bnelearn.util.metrics.ex_post_util_loss(mechanism: Mechanism, bidder_valuations: Tensor, bid_profile: Tensor, bidder: Bidder, grid: Tensor, half_precision=False)[source]¶
Estimates a bidder’s ex post util_loss in the current bid_profile vs a potential grid, i.e. the potential benefit of having deviated from the current strategy, as:
\[\texttt{util_loss} = max(0, BR(v_i, b_-i) - u_i(b_i, b_-i))\]- Args:
mechanism player_valuations: the valuations of the player that is to be evaluated bid_profile: (batch_size x n_player x n_items) bidder: a Bidder (used to retrieve valuations and utilities) grid: Option 1: 1d tensor with length grid_size todo for
n_items > 1
,all
grid_size**n_items
combination will be used. Should be replaced by e.g.torch.meshgrid
. Option 2: tensor with shape (grid_size, n_items)- player_position (optional): specific position in which the player will be evaluated
(defaults to player_position of bidder)
half_precision: (optional, bool) Whether to use half precision tensors. default: false
- Returns:
util_loss (batch_size)
Useful: To get the memory used by a tensor (in MB):
(tensor.element_size() * tensor.nelement())/(1024*1024)
- bnelearn.util.metrics.get_best_responses_among_alternatives(env: AuctionEnvironment, player_position: int, agent_observations: Tensor, action_alternatives: Tensor, opponent_batch_size: int) Tuple[Tensor, IntTensor] [source]¶
Wrapper for _get_best_responses_among_alternatives that makes some computations sequentially if device is OOM.
- bnelearn.util.metrics.norm_actions(b1: Tensor, b2: Tensor, p: float = 2) float [source]¶
Calculates the approximate “mean” Lp-norm between two action vectors.
\[\sum_{i=1}^n(1/n \cdot |b_1 - b_2|^p)^{1/p}\]If p = Infty, this evaluates to the supremum.
- bnelearn.util.metrics.norm_strategies(strategy1: Strategy, strategy2: Strategy, valuations: Tensor, p: float = 2) float [source]¶
Calculates the approximate “mean” \(L_p\)-norm between two strategies approximated via Monte-Carlo integration on a sample of valuations that have been drawn according to the prior.
The function \(L_p\) norm is given by
\[\left( \int_V |s_1(v) - s_2(v)|^p dv \right)^{1/p}.\]With Monte-Carlo integration this is approximated by
\[\left( |V|/n \cdot \sum_i^n(|s1(v) - s2(v)|^p) \right)^{1/p}\]where \(|V|\) is the volume of the set \(V\). Here, we ignore the volume. This gives us the RMSE for \(L_2\), supremum for \(L\)-infty, etc.
- bnelearn.util.metrics.norm_strategy_and_actions(strategy, actions, valuations: Tensor, p: float = 2, componentwise=False) Tensor [source]¶
Calculates the norm as above, but given one action vector and one strategy. The valuations must match the given actions.
This helper function is useful when recalculating an action vector is prohibitive and it should be reused.
- Args:
strategy: Strategy actions: torch.Tensor valuations: torch.Tensor p: float=2 componentwise: bool=False, only returns smallest norm of all output
dimensions if true
- Returns:
norm: (scalar Tensor)
bnelearn.util.mpc module¶
This module contains the implementation of our custom GPU-enabled solver for batched constrained quadratic programs, based on Mehrotra’s Predictor-Corrector-Method (MPC).
authors:
Anne Christopher Stefan Heidekrüger (@heidekrueger) Paul Sutterer
- class bnelearn.util.mpc.MpcSolver(max_iter=20)[source]¶
Bases:
object
A batched qp-solver that solves batches of QPs of the form
min 0.5 x.T Q x + q.T x s.t. Gx <= h
Ax = b
with problem sice n (i.e. \(x\in\mathbb{R}^n}\)) , n_ineq many inequality constraints and n_eq equality constraints.
The device and dtype used by the solver will be inferred from Q.
- Args:
Q (torch.Tensor of dimension (n_batches, n, n)): A batch of positive definite n-by-n matrices. q (Tensor of dimension (n_batches, n)) G (Tensor of dimension (n_batches, n_ineq, n)) h (Tensor of dimension (n_batches, n_ineq)) A (Tensor of dimension (n_batches, n_eq, n)) b (Tensor of dimension (n_batches, n_eq)) refine: bool. When set to True, if after max_iter iterations there are
still batches with residuals over 1e-6, the algorithm will run for another max_iter iterations, up to two additional times.
- print_warning (bool): if True, will print warnings if after three runs of max_iter iterations,
the algorithm still hasn’t converged sufficiently.
bnelearn.util.tensor_util module¶
This module implements util functions for PyTorch tensor operations.
- class bnelearn.util.tensor_util.GaussLayer(**kwargs)[source]¶
Bases:
Module
Custom layer for normally distributed predictions (non-negative).
Has no trainable parameters.
- forward(x, deterministic=False, pretrain=False)[source]¶
Defines the computation performed at every call.
Should be overridden by all subclasses.
Note
Although the recipe for forward pass needs to be defined within this function, one should call the
Module
instance afterwards instead of this since the former takes care of running the registered hooks while the latter silently ignores them.
- training: bool¶
- class bnelearn.util.tensor_util.UniformLayer(**kwargs)[source]¶
Bases:
Module
Custom layer for predictions following a uniform distribution.
Has no trainable parameters.
- forward(x, deterministic=False, pretrain=False)[source]¶
Defines the computation performed at every call.
Should be overridden by all subclasses.
Note
Although the recipe for forward pass needs to be defined within this function, one should call the
Module
instance afterwards instead of this since the former takes care of running the registered hooks while the latter silently ignores them.
- training: bool¶
- bnelearn.util.tensor_util.apply_average_dynamic_mini_batching(function: callable, batch_size: int, shape, device) List[Tensor] [source]¶
- bnelearn.util.tensor_util.apply_with_dynamic_mini_batching(function: callable, args: Tensor, mute: bool = False) List[Tensor] [source]¶
Apply the function function batch wise to the tensor argument args with error handling for CUDA Out-Of-Memory problems. Starting with the full batch, this method will cut the batch size in half until the operation succeeds (or a non-CUDA-OOM error occurs).
NOTE: The automatic error handling applies to CUDA memory limits only. This function does not provide any benefits when processing on CPU with regular RAM.
- Args:
function :callable: function to be evaluated. args :torch.Tensor: pytorch.tensor arguments passed to function. mute :bool: Suppress console output.
- Returns:
function evaluated at args.
- bnelearn.util.tensor_util.batched_index_select(input: Tensor, dim: int, index: Tensor) Tensor [source]¶
Extends the torch
index_select
function to be used for multiple batches at once.This code is borrowed from https://discuss.pytorch.org/t/batched-index-select/9115/11.
- author:
dashesy
- args:
input :torch.Tensor: Tensor which is to be indexed dim :int: Dimension index: :torch.Tensor: Index tensor which provides the selecting and ordering.
- returns:
Indexed tensor :torch.Tensor:
Module contents¶
Submodules¶
bnelearn.bidder module¶
Bidder module
This module implements players / bidders / agents in games.
- class bnelearn.bidder.Bidder(strategy: Strategy, player_position: Optional[Tensor] = None, batch_size: int = 1, valuation_size: int = 1, observation_size: int = 1, bid_size: int = 1, cuda: str = True, enable_action_caching: bool = False, risk: float = 1.0)[source]¶
Bases:
Player
A player in an auction game. Has a distribution over valuations/types that is common knowledge. These valuations correspond to the ´n_items´ available.
- Attributes:
batch_size: corresponds to the number of individual auctions. descending_valuations: if is true, the valuations will be returned
in decreasing order.
- enable_action_caching: determines whether actions should be cached and
retrieved from memory, rather than recomputed as long as valuations haven’t changed.
TODO …
- property cached_observations¶
- property cached_valuations¶
- get_action(observations=None, deterministic: bool = False)[source]¶
Calculate action from given observations, or retrieve from cache
- get_utility(allocations, payments, valuations=None)[source]¶
For a batch of valuations, allocations, and payments of the bidder, return their utility.
Can handle multiple batch dimensions, e.g. for allocations a shape of ( outer_batch_size, inner_batch_size, n_items). These batch dimensions are kept in returned payoff.
- get_welfare(allocations, valuations=None)[source]¶
For a batch of allocations return the player’s welfare.
If valuations are not specified, welfare is calculated for self.valuations.
Can handle multiple batch dimensions, e.g. for valuations a shape of (…, batch_size, n_items). These batch dimensions are kept in returned welfare.
- class bnelearn.bidder.CombinatorialBidder(**kwargs)[source]¶
Bases:
Bidder
Bidder in combinatorial auctions.
Note: Currently only set up for full LLG setting.
- get_welfare(allocations, valuations: Optional[Tensor] = None) Tensor [source]¶
For a batch of allocations return the player’s welfare.
If valuations are not specified, welfare is calculated for self.valuations.
Can handle multiple batch dimensions, e.g. for valuations a shape of (…, batch_size, n_items). These batch dimensions are kept in returned welfare.
- class bnelearn.bidder.Contestant(strategy: Strategy, player_position: Optional[Tensor] = None, batch_size: int = 1, valuation_size: int = 1, observation_size: int = 1, bid_size: int = 1, cuda: str = True, enable_action_caching: bool = False, risk: float = 1.0)[source]¶
Bases:
Bidder
- get_utility(winning_probabilities, payments, valuations=None)[source]¶
For a batch of valuations, allocations, and payments of the contestant, return their utility.
Can handle multiple batch dimensions, e.g. for allocations a shape of ( outer_batch_size, inner_batch_size, n_items). These batch dimensions are kept in returned payoff.
- get_welfare(payments, valuations=None)[source]¶
For a batch of allocations return the player’s welfare.
If valuations are not specified, welfare is calculated for self.valuations.
Can handle multiple batch dimensions, e.g. for valuations a shape of (…, batch_size, n_items). These batch dimensions are kept in returned welfare.
- class bnelearn.bidder.CrowdsourcingContestant(strategy: Strategy, player_position: int, batch_size: int, enable_action_caching: bool = False, crowdsourcing_values: bool = True, value_contest: bool = True)[source]¶
Bases:
Bidder
- get_utility(allocations, payments, ability=None)[source]¶
For a batch of valuations, allocations, and payments of the contestant, return their utility.
Can handle multiple batch dimensions, e.g. for allocations a shape of ( outer_batch_size, inner_batch_size, n_items). These batch dimensions are kept in returned payoff.
- class bnelearn.bidder.MatrixGamePlayer(strategy, player_position=None, batch_size=1, cuda=True)[source]¶
Bases:
Player
A player playing a matrix game
- class bnelearn.bidder.Player(strategy, player_position=None, batch_size=1, cuda=True)[source]¶
Bases:
ABC
A player in a game, determined by her - strategy - utility function over outcomes
bnelearn.environment module¶
This module contains environments - a collection of players and possibly state histories that is used to control game playing and implements reward allocation to agents.
- class bnelearn.environment.AuctionEnvironment(mechanism: Mechanism, agents: Iterable[Bidder], valuation_observation_sampler: ValuationObservationSampler, batch_size=100, n_players=None, strategy_to_player_closure: Optional[Callable[[Strategy], Bidder]] = None, redraw_every_iteration: bool = False)[source]¶
Bases:
Environment
An environment of agents to play against and evaluate strategies.
- Args:
… (TODO: document) correlation_structure
- strategy_to_bidder_closure: A closure (strategy, batch_size) -> Bidder to
transform strategies into a Bidder compatible with the environment
- draw_conditionals(conditioned_player: int, conditioned_observation: Tensor, inner_batch_size: Optional[int] = None, device: Optional[str] = None) Tuple[Tensor, Tensor] [source]¶
Draws a conditional valuation / observation profile based on a (vector of) fixed observations for one player.
Total batch size will be conditioned_observation.shape[0] x inner_batch_size
- draw_valuations()[source]¶
Draws a new valuation and observation profile
- returns/yields:
nothing
- side effects:
updates agent’s valuations and observation states
- get_allocation(agent, redraw_valuations: bool = False, aggregate: bool = True) Tensor [source]¶
Returns allocation of a single player against the environment.
- get_efficiency(redraw_valuations: bool = False) float [source]¶
Average percentage that the actual welfare reaches of the maximal possible welfare over a batch.
- Args:
- redraw_valuations (:bool:) whether or not to redraw the valuations of
the agents.
- Returns:
- efficiency (:float:) Percentage that the actual welfare reaches of
the maximale possible welfare. Averaged over batch.
- get_revenue(redraw_valuations: bool = False) float [source]¶
Returns the average seller revenue over a batch.
- Args:
- redraw_valuations (bool): whether or not to redraw the valuations of
the agents.
- Returns:
revenue (float): average of seller revenue over a batch of games.
- get_reward(agent: Bidder, redraw_valuations: bool = False, aggregate: bool = True, regularize: float = 0.0, return_allocation: bool = False, smooth_market: bool = False, deterministic: bool = False) Tensor [source]¶
Returns reward of a single player against the environment, and optionally additionally the allocation of that player. Reward is calculated as average utility for each of the batch_size x env_size games
- class bnelearn.environment.Environment(agents: Iterable, n_players=2, batch_size=1, strategy_to_player_closure: Optional[Callable] = None, **kwargs)[source]¶
Bases:
ABC
An Environment object ‘manages’ a repeated game, i.e. manages the current players and their models, collects players’ actions, distributes rewards, runs the game itself and allows ‘simulations’ as in ‘how would a mutated player do in the current setting’?
- abstract get_reward(agent: Player, **kwargs) Tensor [source]¶
Return reward for a player playing a certain strategy
- get_strategy_action_and_reward(strategy: Strategy, player_position: int, redraw_valuations=False, **strat_to_player_kwargs) Tensor [source]¶
Returns reward of a given strategy in given environment agent position.
- get_strategy_reward(strategy: Strategy, player_position: int, redraw_valuations=False, aggregate_batch=True, regularize: float = 0, smooth_market: bool = False, deterministic: bool = False, **strat_to_player_kwargs) Tensor [source]¶
Returns reward of a given strategy in given environment agent position.
- Args:
strategy: the strategy to be evaluated player_position: the player position at which the agent will be evaluated redraw_valuation: whether to redraw valuations (default false) aggregate_batch: whether to aggregate rewards into a single scalar (True),
or return batch_size many rewards (one for each sample). Default True
strat_to_player_kwargs: further arguments needed for agent creation regularize: paramter that penalizes high action values (e.g. if we
get the same utility with different actions, we prefer the lower one). Default value of zero corresponds to no regularization.
- class bnelearn.environment.MatrixGameEnvironment(game: MatrixGame, agents, n_players=2, batch_size=1, strategy_to_player_closure=None, **kwargs)[source]¶
Bases:
Environment
An environment for matrix games.
Important features of matrix games for implementation:
not necessarily symmetric, i.e. each player has a fixed position
agents strategies do not take any input, the actions only depend on the game itself (no Bayesian Game)
bnelearn.learner module¶
Implements multi-agent learning rules
- class bnelearn.learner.AESPGLearner(model: NeuralNetStrategy, environment: Environment, hyperparams: dict, optimizer_type: Type[Optimizer], optimizer_hyperparams: dict, strat_to_player_kwargs: Optional[dict] = None)[source]¶
Bases:
GradientBasedLearner
Implements Deterministic Policy Gradients http://proceedings.mlr.press/v32/silver14.pdf with ES-pseudogradients of dQ/da
- class bnelearn.learner.DDPGLearner[source]¶
Bases:
GradientBasedLearner
Implements Deep Deterministic Policy Gradients (Lilicrap et al 2016)
- class bnelearn.learner.DPGLearner[source]¶
Bases:
GradientBasedLearner
Implements Deterministic Policy Gradients
http://proceedings.mlr.press/v32/silver14.pdf
via directly calculating dQ/da and da/dtheta
- class bnelearn.learner.DummyNonLearner(model: Module, environment: Environment, hyperparams: dict, optimizer_type: Type[Optimizer], optimizer_hyperparams: dict, strat_to_player_kwargs: Optional[dict] = None)[source]¶
Bases:
GradientBasedLearner
A learner that does nothing.
- class bnelearn.learner.ESPGLearner(hyperparams: dict, **kwargs)[source]¶
Bases:
GradientBasedLearner
Neural Self-Play with Evolutionary Strategy Pseudo-PG as proposed in Bichler et. al (2021).
Uses pseudo-policy gradients calculated as
(rewards - baseline).mean() * epsilons / sigma**2
over a population of models perturbed by parameter noise epsilon yielding perturbed rewards.
- Arguments:
model: bnelearn.bidder environment: bnelearn.Environment hyperparams: dict
- (required:)
population_size: int sigma: float scale_sigma_by_model_size: bool
- (optional:)
- normalize_gradients: bool (default: False)
If true will scale rewards to N(0,1) in weighted-noise update: (F - baseline).mean()/sigma/F.std() resulting in an (approximately) normalized vector pointing in the same direction as the true gradient. (normalization requires small enough sigma!) If false or not provided, will approximate true gradient using current utility as a baseline for variance reduction.
- baseline: (‘current_reward’, ‘mean_reward’ or a float.)
If ‘current_reward’, will use current utility before update as a baseline. If ‘mean_reward’, will use mean of candidate rewards.
For small perturbations, ‘mean_reward’ is cheaper to compute (one fewer game played) and yields slightly lower gradient sample variance but yields a biased estimate of the true gradient:
Expect(ES_grad with mean) = (pop_size - 1) / pop_size * true_grad
If a float is given, will use that float as reward. Defaults to ‘current_reward’ if normalize_gradients is False, or to ‘mean_reward’ if normalize_gradients is True.
- regularization: dict of
initial_strength: float, initial penalization factor of bid value regularize_decay: float, decay rate by which the regularization factor
is multiplied each iteration.
- symmetric_sampling: bool
whether or not we sample symmetric pairs of perturbed parameters, e.g. p + eps and p - eps.
- optimizer_type: Type[torch.optim.Optimizer]
A class implementing torch’s optimizer interface used for parameter update step.
- strat_to_player_kwargs: dict
dict of arguments provided to environment used for evaluating utility of current and candidate strategies.
- class bnelearn.learner.GradientBasedLearner(model: Module, environment: Environment, optimizer_type: Type[Optimizer], optimizer_hyperparams: dict, scheduler_type: Optional[Type[_LRScheduler]] = None, scheduler_hyperparams: Optional[dict] = None, strat_to_player_kwargs: Optional[dict] = None, smooth_market: bool = False, log_gradient_variance: bool = False)[source]¶
Bases:
Learner
A learning rule that is based on computing some version of (pseudo-) gradient, then applying an SGD-like update via a
torch.optim.Optimizer
- update_strategy(closure: Optional[Callable] = None) Tensor [source]¶
Performs one model-update to the player’s strategy.
- Params:
- closure: (optional) Callable that recomputes model loss.
Required by some optimizers such as LBFGS. When given, optimizer.step() (and thus this function) return the last evaluated loss. (Usually evaluated BEFORE the model update). For correct usage see: https://pytorch.org/docs/stable/optim.html#optimizer-step-closure
Returns: None or loss evaluated by closure. (See above.)
- class bnelearn.learner.Learner[source]¶
Bases:
ABC
A learning rule used to update a player’s policy in self-play
- class bnelearn.learner.PGLearner(hyperparams: dict, **kwargs)[source]¶
Bases:
GradientBasedLearner
Neural Self-Play with directly computed Policy Gradients.
- class bnelearn.learner.PSOLearner(model: Module, environment: Environment, hyperparams: dict, optimizer_type: Type[Optimizer], optimizer_hyperparams: dict, scheduler_type: Optional[Type[_LRScheduler]] = None, scheduler_hyperparams: Optional[dict] = None, strat_to_player_kwargs: Optional[dict] = None, smooth_market: bool = False, log_gradient_variance: bool = False)[source]¶
Bases:
Learner
Implements the Particle Swarm Optimization Algorithm as a Learner Particles represent a possible solutions to the model parameters. Every update step they move one step in the search space to sample a new solution point. They are guided by their previously best found solution (personal best position) and the best solution found by the entire swarm (best position) NOTE: dim = number of parameters in the model to be optimized Arguments:
model: bnelearn.bidder environment: bnelearn.Environment hyperparams: dict
- (required:)
- swarm_size: int
Number of particles in the swarm
- topology: str
Defines the communication network of the swarm If ‘global’, particles are drawn to the global best position of the swarm.
Neighborhood size = swarm size
- If ‘ring’, particles are drawn to the best position in their neighborhood.
Particles form a neighborhood based on their position in the population array. The first and last particles are connected to form a ring structure. Neighborhood size = 3. E.g., neighborhood of particle i: particle i-1, particle i, particle i+1
- If ‘von_neumann’, particles are drawn to the best position in their neighborhood.
Particles form a neighborhood based on their position in the population matrix. A particle is connected to its left, right, upper and lower neighbor in the matrix. Neighborhood size = 5
- max_velocity: float
Max step size in each direction during one update step If velocity_clamping == False then only used for initialization
- (optional:)
The default values for the inertia weight and the cognition & social ratio are commonly used values performing well form most problem settings. Based on: Clerc, M., & Kennedy, J. (2002) inertia_weight: float, List, Tuple (default: 0.792)
Scales the impact of the old velocity on the new one. If float, will set value as constant If List or Tuple, with lenght == 2, will take the first value as w_max and second as w_min for a linear decreasing inertia weight !!! max number of iteration is hardcoded to 2000 !!!
- cognition_ratio: float (default: 1.49445)
Upper limit for the impact of the personal best solution on the velocity
- social_ratio: float (default: 1.49445)
Upper limit for the impact of the swarm’s best solution on the velocity
- reeval_frequency: int (default: None)
Number of epochs after which the personal and overall bests are reevaluated to prevent false memory introduced by varying batch data
- decrease_fitness: List or Tuple (default None)
The to evaporation constants are used to reduce the remembered fitness of the bests to prevent false memory introduced by varying batch data. !!! Use either ‘reeval_frequency’or ‘decrease_fitness’ !!! with lenght == 2, will take the first value as evaporation constant for personal best and second as evaporation constant for global (neighborhood) best
- pretrain_deviation: float (default: 0)
If pretrain_deviation > 0 the positions will be initialized as: model.parameters + N(mean=0.0, std=pretrain_deviation) otherwise positions will be initialized randomly over the whole search space
- bound_handling: bool (default: False)
If true will clamp particle’s positions in each dim to the interval [-max_position, max_position]
- velocity_clamping: bool (default: True)
If true will clamp particle’s velocities in each dim to the interval [-max_velocity, max_velocity] before adding to the positions
- optimizer_type: Type[torch.optim.Optimizer]
A class implementing torch’s optimizer interface used for parameter update step. PSO does not need an torch optimizer to compute an parameter update step. -> currently only used to have an consistent interface with other learners
optimizer_hyperparams: dict strat_to_player_kwargs: dict
Dict of arguments provided to environment used for evaluating utility of current and candidate strategies.
- class bnelearn.learner.ReinforceLearner(hyperparams: Optional[dict] = None, **kwargs)[source]¶
Bases:
GradientBasedLearner
REINFORCE Learner. Also known as Score function estimator.
See https://link.springer.com/article/10.1007/BF00992696 and https://pytorch.org/docs/stable/distributions.html.
bnelearn.strategy module¶
Implementations of strategies for playing in Auctions and Matrix Games.
- class bnelearn.strategy.ClosureStrategy(closure: Callable, parallel: int = 0, mute=False)[source]¶
Bases:
Strategy
A strategy specified by a closure
- Args:
closure: Callable a function or lambda that defines the strategy parallel: int (optional) maximum number of processes for parallel execution of closure. Default is
0/1 (i.e. no parallelism)
- class bnelearn.strategy.FictitiousNeuralPlayStrategy(n_actions, beliefs, init_weight_normalization=False)[source]¶
Bases:
MatrixGameStrategy
,Module
An implementation of the concept of Fictitious Play with NN. An implementation inspired by: https://www.groundai.com/project/deep-fictitious-play-for-stochastic-differential-games2589/2 Take the beliefs about others strategies as input for the NN.
- forward(x)[source]¶
Defines the computation performed at every call.
Should be overridden by all subclasses.
Note
Although the recipe for forward pass needs to be defined within this function, one should call the
Module
instance afterwards instead of this since the former takes care of running the registered hooks while the latter silently ignores them.
- training: bool¶
- class bnelearn.strategy.FictitiousPlayMixedStrategy(game: Game, initial_beliefs: Optional[Iterable[Tensor]] = None)[source]¶
Bases:
FictitiousPlaySmoothStrategy
Play (communicate) probabilities for play (same as in smooth FP) instead of one action. One strategy should be shared among all players such that they share the same beliefs. This is purely fictitious since it does not simulate actions.
- class bnelearn.strategy.FictitiousPlaySmoothStrategy(game: Game, initial_beliefs: Optional[Iterable[Tensor]] = None)[source]¶
Bases:
FictitiousPlayStrategy
Implementation based on Fudenberg (1999) but extended by smooth fictitious play. Randomize action by taking the softmax over the expected utilities for each action and sample. Also, add a temperature (tau) that ensures convergence by becoming smaller.
- class bnelearn.strategy.FictitiousPlayStrategy(game: MatrixGame, initial_beliefs: Optional[Iterable[Tensor]] = None)[source]¶
Bases:
Strategy
Based on description in: Fudenberg, 1999 - The Theory of Learning, Chapter 2.2 Always play best response (that maximizes utility based on current beliefs).
- class bnelearn.strategy.MatrixGameStrategy(n_actions, init_weights=None, init_weight_normalization=False)[source]¶
Bases:
Strategy
,Module
A dummy neural network that encodes and returns a mixed strategy
- forward(x)[source]¶
Defines the computation performed at every call.
Should be overridden by all subclasses.
Note
Although the recipe for forward pass needs to be defined within this function, one should call the
Module
instance afterwards instead of this since the former takes care of running the registered hooks while the latter silently ignores them.
- play(inputs=None, batch_size=1)[source]¶
Takes (private) information as input and decides on the actions an agent should play.
- to(device)[source]¶
Moves and/or casts the parameters and buffers.
This can be called as
- to(device=None, dtype=None, non_blocking=False)[source]
- to(dtype, non_blocking=False)[source]
- to(tensor, non_blocking=False)[source]
- to(memory_format=torch.channels_last)[source]
Its signature is similar to
torch.Tensor.to()
, but only accepts floating point or complexdtype
s. In addition, this method will only cast the floating point or complex parameters and buffers todtype
(if given). The integral parameters and buffers will be moveddevice
, if that is given, but with dtypes unchanged. Whennon_blocking
is set, it tries to convert/move asynchronously with respect to the host if possible, e.g., moving CPU Tensors with pinned memory to CUDA devices.See below for examples.
Note
This method modifies the module in-place.
- Args:
- device (
torch.device
): the desired device of the parameters and buffers in this module
- dtype (
torch.dtype
): the desired floating point or complex dtype of the parameters and buffers in this module
- tensor (torch.Tensor): Tensor whose dtype and device are the desired
dtype and device for all parameters and buffers in this module
- memory_format (
torch.memory_format
): the desired memory format for 4D parameters and buffers in this module (keyword only argument)
- device (
- Returns:
Module: self
Examples:
>>> # xdoctest: +IGNORE_WANT("non-deterministic") >>> linear = nn.Linear(2, 2) >>> linear.weight Parameter containing: tensor([[ 0.1913, -0.3420], [-0.5113, -0.2325]]) >>> linear.to(torch.double) Linear(in_features=2, out_features=2, bias=True) >>> linear.weight Parameter containing: tensor([[ 0.1913, -0.3420], [-0.5113, -0.2325]], dtype=torch.float64) >>> # xdoctest: +REQUIRES(env:TORCH_DOCTEST_CUDA1) >>> gpu1 = torch.device("cuda:1") >>> linear.to(gpu1, dtype=torch.half, non_blocking=True) Linear(in_features=2, out_features=2, bias=True) >>> linear.weight Parameter containing: tensor([[ 0.1914, -0.3420], [-0.5112, -0.2324]], dtype=torch.float16, device='cuda:1') >>> cpu = torch.device("cpu") >>> linear.to(cpu) Linear(in_features=2, out_features=2, bias=True) >>> linear.weight Parameter containing: tensor([[ 0.1914, -0.3420], [-0.5112, -0.2324]], dtype=torch.float16) >>> linear = nn.Linear(2, 2, bias=None).to(torch.cdouble) >>> linear.weight Parameter containing: tensor([[ 0.3741+0.j, 0.2382+0.j], [ 0.5593+0.j, -0.4443+0.j]], dtype=torch.complex128) >>> linear(torch.ones(3, 2, dtype=torch.cdouble)) tensor([[0.6122+0.j, 0.1150+0.j], [0.6122+0.j, 0.1150+0.j], [0.6122+0.j, 0.1150+0.j]], dtype=torch.complex128)
- training: bool¶
- class bnelearn.strategy.NeuralNetStrategy(input_length: int, hidden_nodes: Iterable[int], hidden_activations: Iterable[Module], ensure_positive_output: Optional[Tensor] = None, output_length: int = 1, dropout: float = 0.0, mixed_strategy: Optional[str] = None, bias: bool = True, res_net: bool = False)[source]¶
Bases:
Strategy
,Module
A strategy played by a fully connected neural network
- Args:
- input_length:
dimension of the input layer
- hidden_nodes:
Iterable of number of nodes in hidden layers
- hidden_activations:
Iterable of activation functions to be used in the hidden layers. Should be instances of classes defined in torch.nn.modules.activation
- ensure_positive_output (optional): torch.Tensor
When provided, will check whether the initialized model will return a positive bid anywhere at the given input tensor. Otherwise, the weights will be reinitialized.
- output_length (optional): int
length of output/action vector defaults to 1 (currently given last for backwards-compatibility)
- dropout (optional): float
If not 0, applies AlphaDropout (https://pytorch.org/docs/stable/nn.html#torch.nn.AlphaDropout) to dropout share of nodes in each hidden layer during training.
- mixed_strategy (otional): str
Which distribution to use when the strategy should be mixed.
- res_net (optional): bool
Switch to use ResNet skip connections, s.t. only the difference from a ruthful strategy is learned.
- forward(x, deterministic=False, pretrain=False)[source]¶
Defines the computation performed at every call.
Should be overridden by all subclasses.
Note
Although the recipe for forward pass needs to be defined within this function, one should call the
Module
instance afterwards instead of this since the former takes care of running the registered hooks while the latter silently ignores them.
- play(inputs, deterministic: bool = False)[source]¶
Takes (private) information as input and decides on the actions an agent should play.
- pretrain(input_tensor: Tensor, iterations: int, transformation: Optional[Callable] = None)[source]¶
Performs iters steps of supervised learning on input tensor, in order to find an initial bid function that is suitable for learning.
- args:
input: torch.Tensor, same dimension as self.input_length iters: number of iterations for supervised learning transformation (optional): Callable. Defaulting to identity function if input_length == output_length
returns: Nothing
- reset(ensure_positive_output=None)[source]¶
Re-initialize weights of the Neural Net, ensuring positive model output for a given input.
- training: bool¶
- class bnelearn.strategy.Strategy[source]¶
Bases:
ABC
A Strategy to map (optional) private inputs of a player to actions in a game.
- class bnelearn.strategy.TruthfulStrategy[source]¶
Bases:
Strategy
,Module
A strategy that plays truthful valuations.
- forward(x)[source]¶
Defines the computation performed at every call.
Should be overridden by all subclasses.
Note
Although the recipe for forward pass needs to be defined within this function, one should call the
Module
instance afterwards instead of this since the former takes care of running the registered hooks while the latter silently ignores them.
- play(inputs, deterministic: bool = False)[source]¶
Takes (private) information as input and decides on the actions an agent should play.
- training: bool¶
Module contents¶
Features¶
In this section, we will present the bnelearn package with its most essential features and the auction games and learning algorithms it contains.
Structure¶
I(PV) and non-PV (e.g., common values), with arbitrary priors/correlation profiles, utilities, valuation/observation/bid dimensionalities.
Modular organization allows for easy construction of new markets (e.g., bid languages, etc.) from existing or custom building blocks.
Extensive metrics (learning-related: estimates of “equilibrium quality”, utilities over time, market analysis: efficiency, revenue, individual payoffs) and built-in plotting capacities.
Wide range of predefined settings and building blocks:
Learning rules: Policy Gradients, NPGA, PSO.
Auctions: Single-item, multi-unit, LLG combinatorial auction, LLLLGG combinatorial auction.
Priors/correlations: Uniform and normal priors that are either independent or Bernoulli or constant weight dependent.
Utility functions: Quasi-linear utility (risk-neutral) , risk averse, or risk seeking.
Fully vectorized, CUDA enabled, massive parallelism
For combinatorial auctions: Custom batched, CUDA-enabled QP solver for quadratic auction rules and Gurobi/Cvxpy integration for arbitrary auctions stated as a MIP.
Predefined Auction Settings¶
A diverse set of auction games is implemented in the framework.
Predefined Learners¶
Algorithms for trying to iteratively learn equilibria implement the base class Learner
in the framework. Two noteworthy algorithms that are contained are
Neural self-play with directly computed policy gradients from (Heinrich and Silver, 2016), which is called
PGLearner
,Neural pseudogradient ascent (NPGA), called
ESPGLearner
, from (Bichler et al., 2021),Particle swarm optimization (PSO), called
PSOLearner
, from (Kohring et al., 2022).
Limitations and Alternatives¶
All players in a game must have the same dimensionality (i.e. same-dimensional type-spaces and action-spaces). Current implementations and learners use deterministic/pure continuous actions.
Other existing multi-agent Learning Packages: Other multi-agent learning frameworks, such as OpenSpiel that is a collection of games and algorithms for reinforcement learning and planning or PettingZoo that is a multi-agent extension of the famous OpenAI Gym framework, mainly focus on zero-sum games and on games with discrete action spaces. Crucially, they neither allow an efficient evaluation of running a large batch of games in parallel.