Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

information bottleneck #50

Merged
merged 51 commits into from
Dec 23, 2024
Merged

information bottleneck #50

merged 51 commits into from
Dec 23, 2024

Conversation

nathimel
Copy link
Collaborator

🥳 We now have an IB-BA implementation native to ULTK and a minimal example comparing efficiency analyses using grammatical/LoT complexity to IB.

Here is a summary of the changes I made:

  • Addition of an information_bottleneck submodule within ultk.effcomm, which includes an implementation of the IB-BA algorithm alone and an IBNamingModel.
  • RDOT is no longer a dependency
  • I have not added any tests. :/ I have a couple of very basic ones from RDOT, but I'm not sure how analytically 'true' they are so I just left them out
  • the signaling game example was a minimal example of how to use the agent.py module with adaptive dynamics together with the effcomm module, but ultimately I think its a little outside the scope of ULTK, at least for now. Also, it required RDOT because it involved computing rate distortion (not IB) bounds. Such style of analysis is controversial and I'd rather not have to defend it later on.
  • the color domain is infeasibly slow to compute our own bounds for. I have tried several code optimizations, including jax and torch trying to take advantage of GPU, but BA simply takes too long for a simple working example. Therefore, I think a better example showcasing the utility of ULK is to replicate the results of a different domain that's easier to compute.
  • In light of this, I added a modals example. This reads in natural languages (open to moving those out of this repo and doing url downloads from the modals-effcomm repo instead), performs the same analysis pipeline as the indefinites example, and then computes IB bounds for the domain based on the 'half-credit' communicative utility metric. We then get a nice comparison of the two approaches to efficient communication analysis of modals. I think from start to finish this notebook might take 1 minute to run.
  • I've been working quickly, so feel free to ask me to go back and make changes etc. Cheers!

Nathaniel Imel and others added 30 commits February 5, 2024 16:52
@nathimel nathimel requested a review from shanest November 23, 2024 04:04
@nathimel
Copy link
Collaborator Author

A followup: I'm on the fence about whether to include the colors/ example at all, tbh. There is nothing novel in that notebook that is not covered by https://github.com/nogazs/ib-color-naming/tree/master. This doesn't mean there can't be: we can look at how to convert encoders into ULTK languages, and then measure informativity differently. However, (1) right now effcomm.informativity.informativity infers a binary_matrix by default for each language for its Speaker and Listener, which loses enormous information from the stochastic encoders $q(W|M)$, so making a few extra cells in the notebook to illustrate this will require changes to informativity submodule and to agent.py. Which is fine, but probably best left to another PR. (2) I empirically found measuring informativity to be quite slow (I think because currently we need to build a utility matrix for each call to effcomm.informativity.informativity, which is a (330, 330) matrix, and also we need to evaluate, for each expression in a Language, its Meaning mapping , which itself also requires a large FrozenDict ). On the bright side, the comparisons of diff language measures are present in the modals example.

@nathimel
Copy link
Collaborator Author

What if we replaced the images in the README with the two trade-off plots in the modals example? 🤔 The latter are both original to ULTK, instead of pulled from other papers which we have not exactly replicated in ULTK.

@shanest
Copy link
Collaborator

shanest commented Dec 2, 2024

Amazing stuff, thanks Nathaniel! I will do a detailed code review soon once time permits, but wanted to respond to and mention a few high-level things first:

  • Deleting signaling_games: agreed! I'd been meaning to ask you about this, and the removal of rdot is the perfect occasion.
  • Color: I think we will still want it, for reasons I'm happy to continue to discuss on Zulip and elsewhere.
  • informativity: we can just remove the call to binary_matrix no? We inherited that from RSA-land, but the calculation generalizes to continuous instead of binary cases.
  • Generally: it sounds to me like you're pointing out things that we can refactor in informativity (e.g. can we also have a utility matrix supplied once instead of being calculated every-time) rather than reasons to not include color at all.
  • Modals: this is great to have, amazing 🤩 ! And agree that it's a perfect illustration of differences between ways of measuring the trade-off and the benefits/power of ULTK.
  • Modals data: instead of including all of the nat lang data, can you either (i) just have a script for downloading the data from the modal-typology repo or (ii) do this via a git submodule to that repo? The data shouldn't really be fully duplicated in both places.
  • Main README: that could be a good idea! Let's revisit this (and that README as a whole; I think it needs a little general updating too) in another PR after this one is done. Chris is also adding a learning example, so we'll want to generalize the description of the repo there.

Copy link
Collaborator

@shanest shanest left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great stuff Nathaniel! Only major comments are the ones I mentioned already in the long comment; otherwise, only extremely minor things. Let's walk through the notebook(s) in person in our meeting next week as well :)

# self.xhat_size = len(self.ln_px)

self.result = None # namedtuple
self.results: list[Any] = [] # list of namedtuples
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not list[namedtuple] then? And same for above.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lol good catch

else:
converged = (
it == self.max_it
or np.sum(np.abs(np.exp(self.ln_qxhat_x) - np.exp(prev_q)))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prob just express the bound in log-space instead of exp'ing, but not a huge deal

def ib_kl(py_x: np.ndarray, qy_xhat: np.ndarray) -> np.ndarray:
"""Compute the IB distortion matrix, the KL divergence between p(y|x) and q(y|xhat), in nats."""
# D[p(y|x) || q(y|xhat)],
# input shape `(x, xhat, y)`, output shape `(x, xhat)`
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd be curious to get your thoughts on using jaxtyping to annotate the shape of numpy arrays for methods like these: https://docs.kidger.site/jaxtyping/
It was originally written for jax, but the type annotations work with other libraries like numpy and pytorch

np.exp(self.ln_qy_xhat),
)

def next_result(self, beta, *args, **kwargs) -> IBResult:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice!


return Language(
expressions=tuple(
[
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't need the list [ ... ] wrapper here, e.g. can delete this line and line285

PRECISION = 1e-15


def get_gaussian_noise(shape):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

more params here, with defaults?



##############################################################################
# Probability and Information
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about putting this stuff in the probability sub-module?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. I hope one day we move probability out of effcomm too

@nathimel
Copy link
Collaborator Author

todo from meeting:

  • add some small documentation in modals demo
  • use getitem in meaning for e.meaning[ref]
  • implement iter?

@nathimel nathimel changed the title Ib naming model information bottleneck Dec 23, 2024
Copy link
Collaborator

@shanest shanest left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, Nathaniel! This is great stuff :)

Going to merge now, and just remind of a couple things: (i) we should re-run / update the color example early in the new year; (ii) relatedly, should we close Mickey's branch at this point?; (iii) let's discuss more IB/effcomm analyses from the meeting later as well

@shanest shanest merged commit e2e3b8f into main Dec 23, 2024
@nathimel
Copy link
Collaborator Author

Thanks, Nathaniel! This is great stuff :)

Going to merge now, and just remind of a couple things: (i) we should re-run / update the color example early in the new year; (ii) relatedly, should we close Mickey's branch at this point?; (iii) let's discuss more IB/effcomm analyses from the meeting later as well

Sounds good re (i) and (iii)
(ii) Yes, let's close Mickey's branch.

Cheers!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants