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

Test recognize_digits_conv #4926

Merged
merged 9 commits into from
Oct 19, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion python/paddle/v2/framework/framework.py
Original file line number Diff line number Diff line change
Expand Up @@ -432,11 +432,13 @@ def block(self, index):
def current_block(self):
return self.blocks[self.current_block_idx]

def append_backward(self, target, no_grad_set):
def append_backward(self, target, no_grad_set=None):
"""
return map(param_name -> (grad_name, block_index, op_index))
"""
assert isinstance(target, Variable)
if no_grad_set is None:
no_grad_set = set()

Choose a reason for hiding this comment

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

I think append_backward(self, target, no_grad_set=None): => append_backward(self, target, no_grad_set=set()) will do the same trick?

Copy link
Collaborator Author

@JiayiFeng JiayiFeng Oct 19, 2017

Choose a reason for hiding this comment

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

Well, I think sometimes users will invoke backward by program.append_backward(target=var, no_grad_set=None)

Copy link
Collaborator

Choose a reason for hiding this comment

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

@tonyyang-svail

The default parameter in Python has a huge difference with other languages. It is mutable in Python.

See http://effbot.org/zone/default-values.htm

Choose a reason for hiding this comment

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

I see. Thanks for the heads up.

param_to_grad_info = self.desc.append_backward(target.desc, no_grad_set)
self.sync_with_cpp()
return param_to_grad_info
Expand Down
52 changes: 49 additions & 3 deletions python/paddle/v2/framework/layers.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from paddle.v2.framework.framework import OpProtoHolder, Variable
import re

__all__ = ['fc', 'data', 'cross_entropy', 'conv2d']
__all__ = ['fc', 'data', 'cross_entropy', 'conv2d', 'pool2d']


def fc(input,
Expand Down Expand Up @@ -35,7 +35,10 @@ def fc(input,
"Y": w,
},
outputs={"Out": tmp},
attrs={'x_num_col_dims': num_flatten_dims})
attrs={
'x_num_col_dims': num_flatten_dims,

Choose a reason for hiding this comment

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

x_num_col_dims and num_flatten_dims refer to the same thing. Maybe we should use the same name?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

x_num_col_dims is an attribute of mul op, while num_flatten_dims is an attribute of fc layer. They are at different levels.

'y_num_col_dims': len(input_shape) - num_flatten_dims
})
mul_results.append(tmp)

# sum
Expand Down Expand Up @@ -115,7 +118,6 @@ def func(**kwargs):

_create_op_func_('mean')
_create_op_func_('mul')
_create_op_func_('pool2d')


def cross_entropy(input, label, **kwargs):
Expand Down Expand Up @@ -170,6 +172,13 @@ def conv2d(input,
raise ValueError("num_channels must be divisible by groups.")
num_filter_channels = num_channels / groups

if isinstance(filter_size, int):
filter_size = [filter_size, filter_size]
if isinstance(stride, int):
stride = [stride, stride]
if isinstance(padding, int):
padding = [padding, padding]

input_shape = input.shape
filter_shape = [num_filters, num_filter_channels] + filter_size
filter = helper.create_parameter(
Expand All @@ -190,3 +199,40 @@ def conv2d(input,
pre_act = helper.append_bias_op(pre_bias)

return helper.append_activation(pre_act)


def pool2d(input,
pool_size,
pool_type,
pool_stride=[1, 1],
pool_padding=[0, 0],
global_pooling=False,
program=None):
if pool_type not in ["max", "avg"]:
raise ValueError(
"Unknown pool_type: '%s'. It can only be 'max' or 'avg'.",
str(pool_type))
if isinstance(pool_size, int):
pool_size = [pool_size, pool_size]
if isinstance(pool_stride, int):
pool_stride = [pool_stride, pool_stride]
if isinstance(pool_padding, int):
pool_padding = [pool_padding, pool_padding]

helper = LayerHelper('conv2d', **locals())
dtype = helper.input_dtype()
pool_out = helper.create_tmp_variable(dtype)

helper.append_op(
type="pool2d",
inputs={"X": input},
outputs={"Out": pool_out},
attrs={
"pooling_type": pool_type,
"ksize": pool_size,
"global_pooling": global_pooling,
"strides": pool_stride,
"paddings": pool_padding
})

return pool_out
24 changes: 24 additions & 0 deletions python/paddle/v2/framework/nets.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import paddle.v2.framework.layers as layers


def simple_img_conv_pool(input,
filter_size,
num_filters,
pool_size,
pool_stride,
act,
program=None):
conv_out = layers.conv2d(
input=input,
num_filters=num_filters,
filter_size=filter_size,
act=act,
program=program)

pool_out = layers.pool2d(
input=conv_out,
pool_size=pool_size,
pool_type='max',
pool_stride=pool_stride,
program=program)
return pool_out
51 changes: 40 additions & 11 deletions python/paddle/v2/framework/tests/test_layers.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import paddle.v2.framework.layers as layers
import paddle.v2.framework.nets as nets
from paddle.v2.framework.framework import Program, g_program
import paddle.v2.framework.core as core
import unittest
Expand All @@ -18,7 +19,7 @@ def test_fit_a_line(self):

avg_cost = layers.mean(x=cost, program=program)
self.assertIsNotNone(avg_cost)
program.append_backward(avg_cost, set())
program.append_backward(avg_cost)
print str(program)

def test_recognize_digits_mlp(self):
Expand All @@ -38,24 +39,52 @@ def test_recognize_digits_mlp(self):
cost = layers.cross_entropy(input=predict, label=label, program=program)
avg_cost = layers.mean(x=cost, program=program)
self.assertIsNotNone(avg_cost)
# print str(program)
print str(program)

def test_simple_conv2d(self):
pd = core.ProgramDesc.__create_program_desc__()
program = Program(desc=pd)
images = data_layer(
program = Program()
images = layers.data(
name='pixel', shape=[3, 48, 48], data_type='int32', program=program)
conv2d_layer(
layers.conv2d(
input=images, num_filters=3, filter_size=[4, 4], program=program)

# print str(program)
print str(program)

def test_simple_conv2d(self):
def test_recognize_digits_conv(self):
program = Program()

images = layers.data(
name='pixel', shape=[3, 48, 48], data_type='int32', program=program)
layers.conv2d(
input=images, num_filters=3, filter_size=[4, 4], program=program)
name='pixel',
shape=[1, 28, 28],
data_type='float32',
program=program)
label = layers.data(
name='label', shape=[1], data_type='int32', program=program)
conv_pool_1 = nets.simple_img_conv_pool(
input=images,
filter_size=5,
num_filters=2,
pool_size=2,
pool_stride=2,
act="relu",
program=program)
conv_pool_2 = nets.simple_img_conv_pool(
input=conv_pool_1,
filter_size=5,
num_filters=4,
pool_size=2,
pool_stride=2,
act="relu",
program=program)

predict = layers.fc(input=conv_pool_2,
size=10,
act="softmax",
program=program)
cost = layers.cross_entropy(input=predict, label=label, program=program)
avg_cost = layers.mean(x=cost, program=program)

program.append_backward(avg_cost)

print str(program)

Choose a reason for hiding this comment

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

clean up.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Same as above replied.


Expand Down