Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
P
pytensor
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
testgroup
pytensor
Commits
c430f493
提交
c430f493
authored
8月 12, 2010
作者:
Pascal Lamblin
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Better formatting of doc
上级
7b9efdc2
隐藏空白字符变更
内嵌
并排
正在显示
2 个修改的文件
包含
172 行增加
和
124 行删除
+172
-124
theano_vs_c.txt
doc/extending/theano_vs_c.txt
+1
-0
unittest.txt
doc/extending/unittest.txt
+171
-124
没有找到文件。
doc/extending/theano_vs_c.txt
浏览文件 @
c430f493
...
@@ -22,6 +22,7 @@ Module class
...
@@ -22,6 +22,7 @@ Module class
For example:
For example:
.. code-block:: c
.. code-block:: c
int d = 0;
int d = 0;
int main(int a) {
int main(int a) {
...
...
doc/extending/unittest.txt
浏览文件 @
c430f493
...
@@ -39,15 +39,25 @@ A unittest is a subclass of ``unittest.TestCase``, with member
...
@@ -39,15 +39,25 @@ A unittest is a subclass of ``unittest.TestCase``, with member
functions with names that start with the string ``test``. For
functions with names that start with the string ``test``. For
example:
example:
>>> class MyTestCase(unittest.TestCase):
.. code-block:: python
>>> def test0(self):
>>> pass # test passes cleanly
class MyTestCase(unittest.TestCase):
>>> def test1(self):
def test0(self):
>>> self.failUnless(2+2 == 5) # raises an exception, causes test to fail
pass
>>> def test2(self):
# test passes cleanly
>>> assert 2+2 == 5 # causes error in test (basically a failure, but counted separately)
>>> def test2(self):
def test1(self):
>>> assert 2+2 == 4 # this test has the same name as a previous one, so this is the one that runs.
self.failUnless(2+2 == 5)
# raises an exception, causes test to fail
def test2(self):
assert 2+2 == 5
# causes error in test (basically a failure, but counted separately)
def test2(self):
assert 2+2 == 4
# this test has the same name as a previous one,
# so this is the one that runs.
How to Run Unit Tests ?
How to Run Unit Tests ?
...
@@ -64,22 +74,22 @@ matching a specific criteria and executes them. By default, it will
...
@@ -64,22 +74,22 @@ matching a specific criteria and executes them. By default, it will
find & execute tests case in test*.py files whose method name starts
find & execute tests case in test*.py files whose method name starts
with 'test'.
with 'test'.
Running all unit tests
Running all unit tests
::
>>>
cd Theano/theano
cd Theano/theano
>>>
nosetests
nosetests
Running unit tests with standard out
Running unit tests with standard out
::
>>>
nosetests -s
nosetests -s
Running unit tests contained in a specific .py file
Running unit tests contained in a specific .py file
::
>>>
nosetests <filename>.py
$
nosetests <filename>.py
Running a specific unit test
Running a specific unit test
::
>>>
nosetests <filename>.py:<classname>.<method_name>
nosetests <filename>.py:<classname>.<method_name>
Using unittest module
Using unittest module
~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~
...
@@ -92,22 +102,28 @@ built-in unittest module uses metaclasses to know about all the
...
@@ -92,22 +102,28 @@ built-in unittest module uses metaclasses to know about all the
them all, printing '.' for passed tests, and a stack trace for
them all, printing '.' for passed tests, and a stack trace for
exceptions. The standard footer code in theano's test files is:
exceptions. The standard footer code in theano's test files is:
>>> if __name__ == '__main__':
.. code-block:: python
>>> unittest.main()
if __name__ == '__main__':
unittest.main()
You can also choose to run a subset of the full test suite.
You can also choose to run a subset of the full test suite.
To run all the tests in one or more ``TestCase`` subclasses:
To run all the tests in one or more ``TestCase`` subclasses:
>>> suite = unittest.TestLoader()
.. code-block:: python
>>> suite = suite.loadTestsFromTestCase(MyTestCase0)
>>> suite = suite.loadTestsFromTestCase(MyTestCase1)
suite = unittest.TestLoader()
>>> ...
suite = suite.loadTestsFromTestCase(MyTestCase0)
>>> unittest.TextTestRunner(verbosity=2).run(suite)
suite = suite.loadTestsFromTestCase(MyTestCase1)
...
unittest.TextTestRunner(verbosity=2).run(suite)
To run just a single ``MyTestCase`` member test function called ``test0``:
To run just a single ``MyTestCase`` member test function called ``test0``:
>>> MyTestCase('test0').debug()
.. code-block:: python
MyTestCase('test0').debug()
Folder Layout
Folder Layout
...
@@ -121,12 +137,12 @@ Files containing unittests should be prefixed with the word "test".
...
@@ -121,12 +137,12 @@ Files containing unittests should be prefixed with the word "test".
Optimally every python module should have a unittest file associated
Optimally every python module should have a unittest file associated
with it, as shown below. Unittests testing functionality of module
with it, as shown below. Unittests testing functionality of module
<module>.py should therefore be stored in tests/test_<module>.py
<module>.py should therefore be stored in tests/test_<module>.py
::
>>>
Theano/theano/tensor/basic.py
Theano/theano/tensor/basic.py
>>>
Theano/theano/tensor/elemwise.py
Theano/theano/tensor/elemwise.py
>>>
Theano/theano/tensor/tests/test_basic.py
Theano/theano/tensor/tests/test_basic.py
>>>
Theano/theano/tensor/tests/test_elemwise.py
Theano/theano/tensor/tests/test_elemwise.py
How to Write a Unittest
How to Write a Unittest
...
@@ -154,12 +170,17 @@ need to be added.
...
@@ -154,12 +170,17 @@ need to be added.
Example:
Example:
>>> import unittest
.. code-block:: python
>>> class TestTensorDot(unittest.TestCase):
>>> def test_validity(self):
import unittest
>>> # do stuff
class TestTensorDot(unittest.TestCase):
>>> def test_invalid_dims(self):
def test_validity(self):
>>> # do more stuff
# do stuff
...
def test_invalid_dims(self):
# do more stuff
...
Test cases can define a special setUp method, which will get called
Test cases can define a special setUp method, which will get called
before each test method is executed. This is a good place to put
before each test method is executed. This is a good place to put
...
@@ -167,11 +188,13 @@ functionality which is shared amongst all test methods in the test
...
@@ -167,11 +188,13 @@ functionality which is shared amongst all test methods in the test
case (i.e initializing data, parameters, seeding random number
case (i.e initializing data, parameters, seeding random number
generators -- more on this later)
generators -- more on this later)
>>> class TestTensorDot(unittest.TestCase):
.. code-block:: python
>>> def setUp(self):
>>> # data which will be used in various test methods
class TestTensorDot(unittest.TestCase):
>>> self.avals = numpy.array([[1,5,3],[2,4,1]])
def setUp(self):
>>> self.bvals = numpy.array([[2,3,1,8],[4,2,1,1],[1,4,8,5]])
# data which will be used in various test methods
self.avals = numpy.array([[1,5,3],[2,4,1]])
self.bvals = numpy.array([[2,3,1,8],[4,2,1,1],[1,4,8,5]])
Similarly, test cases can define a tearDown method, which will be
Similarly, test cases can define a tearDown method, which will be
implicitely called at the end of each test method.
implicitely called at the end of each test method.
...
@@ -186,21 +209,25 @@ implementation.
...
@@ -186,21 +209,25 @@ implementation.
Example:
Example:
>>> class TestTensorDot(unittest.TestCase):
.. code-block:: python
>>> def setUp(self):
>>> ...
class TestTensorDot(unittest.TestCase):
>>>
def setUp(self):
>>> def test_validity(self):
...
>>> a = T.dmatrix('a')
>>> b = T.dmatrix('b')
def test_validity(self):
>>> c = T.dot(a,b)
a = T.dmatrix('a')
>>> f = theano.function([a,b],[c])
b = T.dmatrix('b')
>>> cmp = f(self.avals,self.bvals) == numpy.dot(self.avals,self.bvals)
c = T.dot(a,b)
>>> self.failUnless(numpy.all(cmp))
f = theano.function([a,b],[c])
cmp = f(self.avals,self.bvals) == numpy.dot(self.avals,self.bvals)
self.failUnless(numpy.all(cmp))
Avoid hard-coding variables, as in the following case:
Avoid hard-coding variables, as in the following case:
>>> self.failUnless(numpy.all(f(self.avals,self.bvals)==numpy.array([[25,25,30,28],[21,18,14,25]])))
.. code-block:: python
self.failUnless(numpy.all(f(self.avals,self.bvals)==numpy.array([[25,25,30,28],[21,18,14,25]])))
This makes the test case less manageable and forces the user to update
This makes the test case less manageable and forces the user to update
the variables each time the input is changed or possibly when the
the variables each time the input is changed or possibly when the
...
@@ -209,7 +236,7 @@ constrains the test case to specific input/output data pairs. The
...
@@ -209,7 +236,7 @@ constrains the test case to specific input/output data pairs. The
section on random values covers why this might not be such a good
section on random values covers why this might not be such a good
idea.
idea.
Here is a list of useful functions, as defined by TestCase:
Here is a list of useful functions, as defined by TestCase:
* checking the state of boolean variables: assert, failUnless,
* checking the state of boolean variables: assert, failUnless,
assertTrue, failIf, assertFalse
assertTrue, failIf, assertFalse
...
@@ -233,17 +260,19 @@ as they can go unnoticed for a long time and a hard to detect
...
@@ -233,17 +260,19 @@ as they can go unnoticed for a long time and a hard to detect
Example:
Example:
>>> class TestTensorDot(unittest.TestCase):
.. code-block:: python
>>> ...
>>> def test_3D_dot_fail(self):
>>> def func():
>>> a = T.TensorType('float64', (False,False,False)) # create 3d tensor
>>> b = T.dmatrix()
>>> c = T.dot(a,b) # we expect this to fail
>>> # above should fail as dot operates on 2D tensors only
>>> self.failUnlessRaises(TypeError, func)
Useful functions, as defined by TestCase:
class TestTensorDot(unittest.TestCase):
...
def test_3D_dot_fail(self):
def func():
a = T.TensorType('float64', (False,False,False)) # create 3d tensor
b = T.dmatrix()
c = T.dot(a,b) # we expect this to fail
# above should fail as dot operates on 2D tensors only
self.failUnlessRaises(TypeError, func)
Useful functions, as defined by TestCase:
* assertRaises, failUnlessRaises
* assertRaises, failUnlessRaises
...
@@ -256,9 +285,11 @@ given to specify which linker and optimizer to use.
...
@@ -256,9 +285,11 @@ given to specify which linker and optimizer to use.
Example:
Example:
>>> f = T.function([a,b],[c],mode='FAST_RUN')
.. code-block:: python
>>> m = theano.Module()
>>> minstance = m.make(mode='DEBUG_MODE')
f = T.function([a,b],[c],mode='FAST_RUN')
m = theano.Module()
minstance = m.make(mode='DEBUG_MODE')
Whenever possible, unit tests should omit this parameter. Leaving
Whenever possible, unit tests should omit this parameter. Leaving
out the mode will ensure that unit tests use the default mode.
out the mode will ensure that unit tests use the default mode.
...
@@ -287,16 +318,18 @@ generator be seeded at the be beginning of each unit test. This will
...
@@ -287,16 +318,18 @@ generator be seeded at the be beginning of each unit test. This will
ensure that unittest behaviour is consistent from one execution to
ensure that unittest behaviour is consistent from one execution to
another (i.e always pass or always fail).
another (i.e always pass or always fail).
Instead of using
numpy.random.seed
to do this, we encourage users to
Instead of using
``numpy.random.seed``
to do this, we encourage users to
do the following:
do the following:
>>> from theano.tests import unittest_tools
.. code-block:: python
>>>
>>> class TestTensorDot(unittest.TestCase):
from theano.tests import unittest_tools
>>> def setUp(self):
>>> unittest_tools.seed_rng()
class TestTensorDot(unittest.TestCase):
>>> # OR ... call with an explicit seed
def setUp(self):
>>> unittest_tools.seed_rng(234234) #use only if really necessary!
unittest_tools.seed_rng()
# OR ... call with an explicit seed
unittest_tools.seed_rng(234234) #use only if really necessary!
The behaviour of seed_rng is as follows:
The behaviour of seed_rng is as follows:
...
@@ -321,9 +354,11 @@ machine) can simply set ``config.unittest.rseed`` to 'random' (see
...
@@ -321,9 +354,11 @@ machine) can simply set ``config.unittest.rseed`` to 'random' (see
Similarly, to provide a seed to numpy.random.RandomState, simply use:
Similarly, to provide a seed to numpy.random.RandomState, simply use:
>>> rng = numpy.random.RandomState(unittest_tools.fetch_seed())
.. code-block:: python
>>> # OR providing an explicit seed
>>> rng = numpy.random.RandomState(unittest_tools.fetch_seed(1231)) #again not recommended
rng = numpy.random.RandomState(unittest_tools.fetch_seed())
# OR providing an explicit seed
rng = numpy.random.RandomState(unittest_tools.fetch_seed(1231)) #again not recommended
Note that the ability to change the seed from one nosetest to another,
Note that the ability to change the seed from one nosetest to another,
is incompatible with the method of hard-coding the baseline variables
is incompatible with the method of hard-coding the baseline variables
...
@@ -377,57 +412,67 @@ The parameters are as follows:
...
@@ -377,57 +412,67 @@ The parameters are as follows:
It can also be a Python function that calls an op with some of its
It can also be a Python function that calls an op with some of its
inputs being fixed to specific values, or that combine multiple ops.
inputs being fixed to specific values, or that combine multiple ops.
*
pt: the list of numpy.ndarrays to use as inputs to the op
*
``pt``: the list of numpy.ndarrays to use as input values
*
n_tests
: number of times to run the test
*
``n_tests``
: number of times to run the test
*
rng
: random number generator from which to draw random samples
*
``rng``
: random number generator from which to draw random samples
*
eps
: stepsize used in the Finite Difference Method
*
``eps``
: stepsize used in the Finite Difference Method
*
abs_tol
: absolute tolerance used as threshold for gradient comparison
*
``abs_tol``
: absolute tolerance used as threshold for gradient comparison
*
rel_tol
: relative tolerance used as threshold for gradient comparison
*
``rel_tol``
: relative tolerance used as threshold for gradient comparison
In the general case, you can define ``fun`` as you want, as long as it
In the general case, you can define ``fun`` as you want, as long as it
takes as inputs Theano symbolic variables and returns a sinble Theano
takes as inputs Theano symbolic variables and returns a sinble Theano
symbolic variable:
symbolic variable:
>>> def test_verify_exprgrad():
.. code-block:: python
>>> def fun(x,y,z):
>>> return (x + tensor.cos(y)) / (4 * z)**2
def test_verify_exprgrad():
>>> x_val = numpy.asarray([[1], [1.1], [1.2]])
def fun(x,y,z):
>>> y_val = numpy.asarray([0.1, 0.2])
return (x + tensor.cos(y)) / (4 * z)**2
>>> z_val = numpy.asarray(2)
>>> rng = numpy.random.RandomState(42)
x_val = numpy.asarray([[1], [1.1], [1.2]])
>>> tensor.verify_grad(fun, [x_val, y_val, z_val], rng=rng)
y_val = numpy.asarray([0.1, 0.2])
z_val = numpy.asarray(2)
rng = numpy.random.RandomState(42)
tensor.verify_grad(fun, [x_val, y_val, z_val], rng=rng)
Here is an example showing how to use ``verify_grad`` on an Op instance:
Here is an example showing how to use ``verify_grad`` on an Op instance:
>>> def test_flatten_outdimNone():
.. code-block:: python
>>> # Testing gradient w.r.t. all inputs of an op (in this example the op
>>> # being used is Flatten(), which takes a single input).
def test_flatten_outdimNone():
>>> a_val = numpy.asarray([[0,1,2],[3,4,5]], dtype='float64')
# Testing gradient w.r.t. all inputs of an op (in this example the op
>>> rng = numpy.random.RandomState(42)
# being used is Flatten(), which takes a single input).
>>> tensor.verify_grad(tensor.Flatten(), [a_val], rng=rng)
a_val = numpy.asarray([[0,1,2],[3,4,5]], dtype='float64')
rng = numpy.random.RandomState(42)
tensor.verify_grad(tensor.Flatten(), [a_val], rng=rng)
Here is another example, showing how to verify the gradient w.r.t. a subset of
Here is another example, showing how to verify the gradient w.r.t. a subset of
an Op's inputs. This is useful in particular when the gradient w.r.t. some of
an Op's inputs. This is useful in particular when the gradient w.r.t. some of
the inputs cannot be computed by finite difference (e.g. for discrete inputs),
the inputs cannot be computed by finite difference (e.g. for discrete inputs),
which would cause verify_grad to crash.
which would cause ``verify_grad`` to crash.
>>> def test_crossentropy_softmax_grad():
.. code-block:: python
>>> op = tensor.nnet.crossentropy_softmax_argmax_1hot_with_bias
>>> def op_with_fixed_y_idx(x, b):
def test_crossentropy_softmax_grad():
>>> # Input `y_idx` of this Op takes integer values, so we fix them
op = tensor.nnet.crossentropy_softmax_argmax_1hot_with_bias
>>> # to some constant array.
def op_with_fixed_y_idx(x, b):
>>> # Although this op has multiple outputs, we can return only one.
# Input `y_idx` of this Op takes integer values, so we fix them
>>> # Here, we return the first output only.
# to some constant array.
>>> return op(x, b, y_idx=numpy.asarray([0, 2]))[0]
# Although this op has multiple outputs, we can return only one.
>>> x_val = numpy.asarray([[-1, 0, 1], [3, 2, 1]], dtype='float64')
# Here, we return the first output only.
>>> b_val = numpy.asarray([1, 2, 3], dtype='float64')
return op(x, b, y_idx=numpy.asarray([0, 2]))[0]
>>> rng = numpy.random.RandomState(42)
>>> tensor.verify_grad(op_with_fixed_y_idx, [x_val, b_val], rng=rng)
x_val = numpy.asarray([[-1, 0, 1], [3, 2, 1]], dtype='float64')
b_val = numpy.asarray([1, 2, 3], dtype='float64')
rng = numpy.random.RandomState(42)
tensor.verify_grad(op_with_fixed_y_idx, [x_val, b_val], rng=rng)
.. note::
.. note::
...
@@ -449,17 +494,19 @@ this is common, two helper functions exists to make your lives easier:
...
@@ -449,17 +494,19 @@ this is common, two helper functions exists to make your lives easier:
Here is an example of ``makeTester`` generating testcases for the Dot
Here is an example of ``makeTester`` generating testcases for the Dot
product op:
product op:
>>> DotTester = makeTester(name = 'DotTester',
.. code-block:: python
>>> op = dot,
>>> expected = lambda x, y: numpy.dot(x, y),
DotTester = makeTester(name = 'DotTester',
>>> checks = {},
op = dot,
>>> good = dict(correct1 = (rand(5, 7), rand(7, 5)),
expected = lambda x, y: numpy.dot(x, y),
>>> correct2 = (rand(5, 7), rand(7, 9)),
checks = {},
>>> correct3 = (rand(5, 7), rand(7))),
good = dict(correct1 = (rand(5, 7), rand(7, 5)),
>>> bad_build = dict(),
correct2 = (rand(5, 7), rand(7, 9)),
>>> bad_runtime = dict(bad1 = (rand(5, 7), rand(5, 7)),
correct3 = (rand(5, 7), rand(7))),
>>> bad2 = (rand(5, 7), rand(8,3))),
bad_build = dict(),
>>> grad = dict())
bad_runtime = dict(bad1 = (rand(5, 7), rand(5, 7)),
bad2 = (rand(5, 7), rand(8,3))),
grad = dict())
In the above example, we provide a name and a reference to the op we
In the above example, we provide a name and a reference to the op we
want to test. We then provide in the ``expected`` field, a function
want to test. We then provide in the ``expected`` field, a function
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论