# Why use nn.Conv2D over nn.functional.conv2d?

**URL:** <https://discuss.pytorch.org/t/why-use-nn-conv2d-over-nn-functional-conv2d/141>\
**Category:** Uncategorized\
**Created:** [January 22, 2017, 11:34pm UTC](https://discuss.pytorch.org/t/why-use-nn-conv2d-over-nn-functional-conv2d/141 "2017-01-22T23:34:29Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![Kalamaya](https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/kalamaya/32/381_2.png) [@Kalamaya](https://discuss.pytorch.org/u/Kalamaya)\
**Post date:** [January 22, 2017, 11:34pm UTC](https://discuss.pytorch.org/t/why-use-nn-conv2d-over-nn-functional-conv2d/141/1 "2017-01-22T23:34:29Z")

</div>

Hi, I stumbled upon this question because I am trying to have control over how my convolutional weights are initialized.

At any rate, we can create a 2D convolutional layer via [nn.functional.conv2d](http://pytorch.org/docs/nn.html#torch.nn.functional.conv2d), or, via [nn.Conv2d](http://pytorch.org/docs/nn.html#torch.nn.Conv2d)

The API for both of those however seems different.

For the former:

`torch.nn.functional.conv2d(input, weight, bias=None, stride=1, padding=0, dilation=1, groups=1)`

For the latter:

`class torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True)`

So, my questions are the following:

1. Why should I use one over the other?
2. I am trying to initialize my convolutional weights with what I want, so is that possible using nn.Conv2D? I guess one way is to copy over the proper weights that I want, so is that basically it?

Thanks

---

<div class="post-metadata">

**Author:** ![smth](https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/smth/32/13_2.png) [@smth](https://discuss.pytorch.org/u/smth)\
**Post date:** [January 23, 2017, 3:32am UTC](https://discuss.pytorch.org/t/why-use-nn-conv2d-over-nn-functional-conv2d/141/2 "2017-01-23T03:32:01Z")

</div>

1. It is recommended to use `nn.Conv2D` because it uses the `nn.Module` abstraction and nicely ties into the `torch.optim` framework well.

2. Yes, here’s an example of initializing the weights of a ConvNet via a custom weight initialization:  
[https://github.com/pytorch/examples/blob/c6bff8c51eee802be1a77575be0eb3eb5e211ada/dcgan/main.py#L89-L96,L131](https://github.com/pytorch/examples/blob/c6bff8c51eee802be1a77575be0eb3eb5e211ada/dcgan/main.py#L89-L96,L131)  
[https://github.com/pytorch/examples/blob/c6bff8c51eee802be1a77575be0eb3eb5e211ada/dcgan/main.py#L131](https://github.com/pytorch/examples/blob/c6bff8c51eee802be1a77575be0eb3eb5e211ada/dcgan/main.py#L131)
