clab / clab/dynet

affine_transform accepts inputs with mixed batch sizes and returns incorrect results

Open
#1,560 1 comment 0 reactions 0 assignees View on GitHub
major bug
Dominant language
C++
Stars
3.4k
Forks
701
PR merge metrics
No merged PRs in 30d

Description

affine_transform accepts inputs with mixed batch sizes. It implicitly broadcasts expressions with smaller batch sizes in a weird way and returns incorrect values.

Input expressions are broadcast in the batch dimension to match the largest batch size in the inputs.
Apparently, when an expression with n (which can be > 1) batches is broadcast, its (m % n)-th batch is used for the m-th batch.
Does that make sense?

Example:
```
#include "dynet/expr.h"
#include "dynet/model.h"
#include

using namespace std;
using namespace dynet;

int main(int argc, char** argv) {
dynet::initialize(argc, argv);
const unsigned HIDDEN_SIZE = 2;
ComputationGraph cg;
Expression A = random_normal(cg, Dim({HIDDEN_SIZE, HIDDEN_SIZE}, 2));
Expression a = random_normal(cg, Dim({HIDDEN_SIZE}, 3));
Expression I = random_normal(cg, Dim({HIDDEN_SIZE, HIDDEN_SIZE}, 5));
Expression i = random_normal(cg, Dim({HIDDEN_SIZE}, 2));
Expression u = constant(cg, Dim({HIDDEN_SIZE}), 0);
Expression e = affine_transform({u, A, a, I, i});
auto o = as_vector(cg.incremental_forward((e)));
cerr << o.at(0) << " " << o.at(1) << endl;
cerr << o.at(2) << " " << o.at(3) << endl;
cerr << o.at(4) << " " << o.at(5) << endl;
cerr << o.at(6) << " " << o.at(7) << endl;
cerr << o.at(8) << " " << o.at(9) << endl;
cerr << endl;

// batch elements used for the 5-th batch
Expression A2 = pick_batch_elem(A, (unsigned)0);
Expression a2 = pick_batch_elem(a, (unsigned)1);
Expression I2 = pick_batch_elem(I, (unsigned)4);
Expression i2 = pick_batch_elem(i, (unsigned)0);
Expression e2 = affine_transform({u, A2, a2, I2, i2});
auto o2 = as_vector(cg.incremental_forward((e2)));
cerr << o2.at(0) << " " << o2.at(1) << endl;
}
```

Contributor guide

No contributing guide indexed for this repository

Research direction

Start by running the minimal C++ example using dynet/expr.h and dynet/model.h, then inspect the affine_transform entry point and its batch handling. Compare the five-batch output with the explicit pick_batch_elem construction shown in the issue. Done means mixed batch inputs produce correct, consistent results rather than the reported incorrect values.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
machine-learning
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
32/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.