<rss version="2.0">
<channel>
<title>Brandon Rohrer</title>
<link>https://www.brandonrohrer.com</link>
<description>Brandon Rohrer's blog</description>


  <item>
    <title>
    Working examples for redsho hyperparameter optimization
    </title>
    <link>
    https://codeberg.org/brohrer/redsho-examples/src/branch/main
    </link>
    <pubDate>
    Wed, 30 Sep 2026 04:36:00 EDT
    </pubDate>
    <guid>
    https://codeberg.org/brohrer/redsho-examples/src/branch/main
    </guid>
    <description><![CDATA[
<p>
I recently published the
<a href="https://codeberg.org/brohrer/redsho">redsho</a>
package for hyperparameter optimization.
More than anything, I want it to be useful.
I find it helpful to start with a working example. To this end I
created a second repo called
<a href="https://codeberg.org/brohrer/redsho-examples/src/branch/main">redsho-examples</a>
that walks through how to do it.
</p>

<h3>Usage</h3>

<p>
Start with an evaluation function that takes
some hyperparameters as keyword arguments.
</p>

<pre><code>
def evaluate(*, a, b, c):
    return a * b**3 % c
</code></pre>

<p>
(The leading <code>*</code> tells Python that everything that follows
is a required keyword argument.)
</p>

<p>
Build a collection of values to try for each parameter.
</p>

<pre><code>
values = {
    "a": [4, 7, 9],
    "b": [2, 5, 6],
    "c": [5, 8, 11],
}
</code></pre>

<p>
Call the optimizer.
</p>

<pre><code>
from redsho.optimizer import optimize<br>
error, params = optimize(evaluate, values)
</code></pre>

<p>
where <code>error</code> is the lowest error achieved, and <code>params</code>
is the collection of parameter values that achieved it.
</p>

<h3>Examples</h3>
<p>
As of right now, there are 4 examples, each in their own subdirectory:
    <ul>
      <li>
        <code>sinc</code>: optimizes a 2D variant of the sinc function,
        <em>sin(x)/x</em>
      </li>
      <li>
        <code>perf</code>: tests the execution time bottleneck in redsho
        and helps to streamline it
      </li>
      <li>
        <code>xgboost_regression</code>: optimizes an XGBoost regression
        model across a wide variety of hyperparameters and options
      </li>
      <li>
        <code>xgboost_multiclass</code>: same as the previous example,
        but with a multiclass classification problem
      </li>
    </ul>
</p>

<p>
  If you generate any examples of your own that you're comfortable sharing,
  we can add them to the list. :)
</p>

    ]]></description>
  </item>

  <item>
    <title>
    Required keyword args in Python
    </title>
    <link>
    https://peps.python.org/pep-3102/
    </link>
    <pubDate>
    Tue, 29 Sep 2026 04:36:00 EDT
    </pubDate>
    <guid>
    https://peps.python.org/pep-3102/
    </guid>
    <description><![CDATA[

<p>
Cool Python trick I learned: Sometimes you want functions to have
keyword arguments, but you also want them to be required.
This is especially useful when you're passing required arguments
using dictionary expansion, like <code>function(**arg_dict)</code>.
</p>
<p>
I always did this by setting all the parameter keyword defaults to
<code>None</code>, then checking for any <code>None</code> values in
the function. But there's a better way: using the bare <code>*</code>
in the argument list. Everything after the asterisk will be a required
keyword argument.
</p>
<p>
This means that now when I write
</p>

<pre><code>def sum(*, a=None, b=None):
	return a + b
</code></pre>

<p>
I no longer have to check that <code>a</code> and <code>b</code> are not
<code>None</code> in the function, and I can call it with
</p>

<pre><code>arg_dict = {'a': 4, 'b': 9}
print(sum(**arg_dict))
</code></pre>

<p>
You can still put positional and optional keywords before the asterisk.
</p>

<pre><code>
def estimate(a, b, verbose=False, *, method=None, n_iter=None):
    ...
</code></pre>

<p>
It doesn't matter what default value these required kwargs get
because it will always be overwritten.
</p>

    ]]></description>
  </item>

  <item>
    <title>
    redsho: a robust hyperparameter optimizer
    </title>
    <link>
    https://codeberg.org/brohrer/redsho
    </link>
    <pubDate>
    Mon, 28 Sep 2026 06:36:00 EDT
    </pubDate>
    <guid>
    https://codeberg.org/brohrer/redsho
    </guid>
    <description><![CDATA[

<p>
Optimizing models with lots of hyperparameters or functions with many options
is a slog that usually requires a combination community wisdom, obscure
blog posts, and tedious trial and error. Automated methods tend to either
rely on strong assumptions of smoothness or brute force their way through
every permutation. All of these options kind of suck.
</p>

<p style="text-align:center;">
<img alt="Animation of Evolutionary Powell's method finding an optimum"  
src="https://gitlab.com/brohrer/ponderosa/raw/master/ponderosa/landing_page_demo.gif"
style="height: 350px;">
</p>
<p>
I took a swing at an alternative approach called <code>redsho</code>.
It takes a middle ground approach for when the effects of parameters and
options can be wildly non-linear and exhaustive grid search would take
longer than we want to spend. A full description of how it works takes
<a href="https://brandonrohrer.at/evopowell.html">a post of its own</a>,
but its distinguishing feature is that it is evolutionary in nature.
It looks through the parameter combinations it has tried already and
picks one randomly, leaning heavily toward the best performers.
Then it chooses one of the parameters in its collection and tries a few
random values that it hasn't tried before. This process is reflected in
the full name: Robust Evolutionary Direction Set Hyperparameter Optimizer.
</p>
<p>
Check out <a href="https://codeberg.org/brohrer/redsho">the repo</a>).
</p>
    ]]></description>
  </item>


</channel>
</rss>
