提交 b1af7e5d 编写于 作者: F fengjiayi

Add unittests for lookup_table_op

上级 7efdf05a
...@@ -139,7 +139,10 @@ class LookupTableGradCUDAKernel : public framework::OpKernel<T> { ...@@ -139,7 +139,10 @@ class LookupTableGradCUDAKernel : public framework::OpKernel<T> {
auto *d_table_data = d_table_value->data<T>(); auto *d_table_data = d_table_value->data<T>();
auto *d_output_data = d_output->data<T>(); auto *d_output_data = d_output->data<T>();
PADDLE_ENFORCE_EQ(d_table_value->dims(), d_output->dims()); auto d_output_dims = d_output->dims();
PADDLE_ENFORCE_EQ(
d_table_value->dims(),
framework::flatten_to_2d(d_output_dims, d_output_dims.size() - 1));
memory::Copy(gpu_place, d_table_data, gpu_place, d_output_data, memory::Copy(gpu_place, d_table_data, gpu_place, d_output_data,
d_output->numel() * sizeof(T), stream); d_output->numel() * sizeof(T), stream);
......
...@@ -127,7 +127,10 @@ class LookupTableGradKernel : public framework::OpKernel<T> { ...@@ -127,7 +127,10 @@ class LookupTableGradKernel : public framework::OpKernel<T> {
auto *d_output_data = d_output->data<T>(); auto *d_output_data = d_output->data<T>();
auto *d_table_data = d_table_value->data<T>(); auto *d_table_data = d_table_value->data<T>();
PADDLE_ENFORCE_EQ(d_table_value->dims(), d_output->dims()); auto d_output_dims = d_output->dims();
PADDLE_ENFORCE_EQ(
d_table_value->dims(),
framework::flatten_to_2d(d_output_dims, d_output_dims.size() - 1));
memcpy(d_table_data, d_output_data, sizeof(T) * d_output->numel()); memcpy(d_table_data, d_output_data, sizeof(T) * d_output->numel());
} else { } else {
auto *ids = context.Input<LoDTensor>("Ids"); auto *ids = context.Input<LoDTensor>("Ids");
...@@ -137,7 +140,7 @@ class LookupTableGradKernel : public framework::OpKernel<T> { ...@@ -137,7 +140,7 @@ class LookupTableGradKernel : public framework::OpKernel<T> {
auto *ids_data = ids->data<int64_t>(); auto *ids_data = ids->data<int64_t>();
int N = table_dim[0]; int N = table_dim[0];
int D = d_output->dims()[1]; int D = table_dim[1];
auto *d_output_data = d_output->data<T>(); auto *d_output_data = d_output->data<T>();
auto *d_table_data = d_table->mutable_data<T>(context.GetPlace()); auto *d_table_data = d_table->mutable_data<T>(context.GetPlace());
......
...@@ -35,6 +35,22 @@ class TestLookupTableOp(OpTest): ...@@ -35,6 +35,22 @@ class TestLookupTableOp(OpTest):
self.check_grad(['W'], 'Out', no_grad_set=set('Ids')) self.check_grad(['W'], 'Out', no_grad_set=set('Ids'))
class TestLookupTableOpWithTensorIds(OpTest):
def setUp(self):
self.op_type = "lookup_table"
table = np.random.random((17, 31)).astype("float32")
ids = np.random.randint(
low=0, high=17, size=(2, 4, 5, 1)).astype("int64")
self.inputs = {'W': table, 'Ids': ids}
self.outputs = {'Out': table[ids.flatten()].reshape((2, 4, 5, 31))}
def test_check_output(self):
self.check_output()
def test_check_grad(self):
self.check_grad(['W'], 'Out', no_grad_set=set('Ids'))
class TestLookupTableOpWithPadding(TestLookupTableOp): class TestLookupTableOpWithPadding(TestLookupTableOp):
def test_check_output(self): def test_check_output(self):
ids = np.squeeze(self.inputs['Ids']) ids = np.squeeze(self.inputs['Ids'])
...@@ -49,16 +65,29 @@ class TestLookupTableOpWithPadding(TestLookupTableOp): ...@@ -49,16 +65,29 @@ class TestLookupTableOpWithPadding(TestLookupTableOp):
pass pass
class TestLookupTableWIsSelectedRows(OpTest): class TestLookupTableOpWithTensorIdsAndPadding(TestLookupTableOpWithTensorIds):
def check_with_place(self, place): def test_check_output(self):
scope = core.Scope() ids = self.inputs['Ids']
flatten_idx = ids.flatten()
padding_idx = np.random.choice(flatten_idx, 1)[0]
self.outputs['Out'][np.squeeze(ids == padding_idx)] = np.zeros(31)
self.attrs = {'padding_idx': long(padding_idx)}
self.check_output()
def test_check_grad(self):
# Since paddings are not trainable and fixed in forward, the gradient of
# paddings makes no sense and we don't test the gradient here.
pass
# create and initialize Id Variable
class TestLookupTableWIsSelectedRows(OpTest):
def prepare_ids(self, scope, place):
ids_tensor = scope.var('Ids').get_tensor() ids_tensor = scope.var('Ids').get_tensor()
ids_array = np.array([[0], [4], [3], [5]]).astype("int64") ids_array = np.array([[0], [4], [3], [5]]).astype("int64")
ids_tensor.set(ids_array, place) ids_tensor.set(ids_array, place)
return ids_array
# create and initialize W Variable def prepare_w(self, scope, place):
rows = [0, 1, 2, 3, 4, 5, 6] rows = [0, 1, 2, 3, 4, 5, 6]
row_numel = 12 row_numel = 12
...@@ -71,8 +100,22 @@ class TestLookupTableWIsSelectedRows(OpTest): ...@@ -71,8 +100,22 @@ class TestLookupTableWIsSelectedRows(OpTest):
w_tensor = w_selected_rows.get_tensor() w_tensor = w_selected_rows.get_tensor()
w_tensor.set(w_array, place) w_tensor.set(w_array, place)
# create Out Variable def create_out_tensor(self, scope, place):
out_tensor = scope.var('Out').get_tensor() return scope.var('Out').get_tensor()
def check_result(self, ids_array, result_array):
# all(): return True if all elements of the iterable are true (or if the iterable is empty)
for idx, row in enumerate(ids_array):
assert (row[0] == result_array[idx]).all()
def check_with_place(self, place):
scope = core.Scope()
ids_array = self.prepare_ids(scope, place)
self.prepare_w(scope, place)
out_tensor = self.create_out_tensor(scope, place)
# create and run lookup_table operator # create and run lookup_table operator
lookup_table = Operator("lookup_table", W='W', Ids='Ids', Out='Out') lookup_table = Operator("lookup_table", W='W', Ids='Ids', Out='Out')
...@@ -80,9 +123,8 @@ class TestLookupTableWIsSelectedRows(OpTest): ...@@ -80,9 +123,8 @@ class TestLookupTableWIsSelectedRows(OpTest):
# get result from Out # get result from Out
result_array = np.array(out_tensor) result_array = np.array(out_tensor)
# all(): return True if all elements of the iterable are true (or if the iterable is empty)
for idx, row in enumerate(ids_array): self.check_result(ids_array, result_array)
assert (row[0] == result_array[idx]).all()
def test_w_is_selected_rows(self): def test_w_is_selected_rows(self):
places = [core.CPUPlace()] places = [core.CPUPlace()]
...@@ -91,5 +133,19 @@ class TestLookupTableWIsSelectedRows(OpTest): ...@@ -91,5 +133,19 @@ class TestLookupTableWIsSelectedRows(OpTest):
self.check_with_place(place) self.check_with_place(place)
class TestLookupTableWithTensorIdsWIsSelectedRows(
TestLookupTableWIsSelectedRows):
def prepare_ids(self, scope, place):
ids_tensor = scope.var('Ids').get_tensor()
ids_array = np.random.randint(
low=0, high=6, size=(2, 4, 3, 1)).astype("int64")
ids_tensor.set(ids_array, place)
return ids_array
def check_result(self, ids_array, result_array):
for idx, row in np.ndenumerate(ids_array):
assert (row == result_array[idx]).all()
if __name__ == "__main__": if __name__ == "__main__":
unittest.main() unittest.main()
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册