Custom Function - object has no attribute 'dim'

username: caiusdebucean
cooked: <p>Hello,<br>
So I’ve been trying to create a custom function and test things out, but I can’t seem to know how to make the data or function work. I’m a little confused. Here is the code:</p>
<pre><code class="lang-auto">from collections import OrderedDict
import numpy as np
import torch
from torch import nn
from torch import optim
import torch.nn.functional as F
from torchvision import datasets, transforms
import math


class Custom(nn.Module):
    def __init__(self, weights = 1, dim = 1):
        super().__init__()
        self.weights = weights

    def forward(self, input):
        a = 2
        x = input
        y = a + math.log(x)
        return y


transform = transforms.Compose([transforms.ToTensor(),
  transforms.Normalize((0.5,), (0.5,))
])

trainset = datasets.MNIST('MNIST_data/', download=True, train=True, transform=transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=64, shuffle=True)

input_size = 784
hidden_sizes = [128, 64]
output_size = 10

class Network(nn.Module):
    def __init__(self):
        super().__init__()
        self.fc1 = nn.Linear(784, 128)
        self.fc2 = nn.Linear(128, 64)
        self.fc3 = nn.Linear(64, 10)
        
    def forward(self, x):
        x = Custom(x)
        x = self.fc1(x)
        x = Custom(x)
        x = self.fc2(x)
        x = Custom(x)
        x = self.fc3(x)
        
        
        return x

model = Network()

criterion = nn.CrossEntropyLoss() 
optimizer = optim.SGD(model.parameters(), lr=0.003)


#some tutorial
epochs = 3
print_every = 40
steps = 0
for e in range(epochs):
    running_loss = 0
    for images, labels in iter(trainloader):
        steps += 1
        images.resize_(images.size()[0], 784)
        optimizer.zero_grad()
        output = model.forward(images)
        loss = criterion(output, labels)
        loss.backward()
        optimizer.step()
        running_loss += loss.item()
        
        if steps % print_every == 0:
            print("Epoch: {}/{}... ".format(e+1, epochs),
                    "Loss: {:.4f}".format(running_loss/print_every))
            
            running_loss = 0
torch.save(model.state_dict(),'MNIST_' + str(epochs) + 'ep.pth')
print("I saved the model: " + 'MNIST_' + str(epochs) + 'ep.pth')
</code></pre>
<p>The error I get is</p>
<pre><code class="lang-auto">Traceback (most recent call last):
  File "MNIST.py", line 68, in &lt;module&gt;
    output = model.forward(images)
  File "MNIST.py", line 43, in forward
    x = self.fc1(x)
  File "/home/caius/anaconda3/envs/Tutorials/lib/python3.8/site-packages/torch/nn/modules/module.py", line 532, in __call__
    result = self.forward(*input, **kwargs)
  File "/home/caius/anaconda3/envs/Tutorials/lib/python3.8/site-packages/torch/nn/modules/linear.py", line 87, in forward
    return F.linear(input, self.weight, self.bias)
  File "/home/caius/anaconda3/envs/Tutorials/lib/python3.8/site-packages/torch/nn/functional.py", line 1368, in linear
    if input.dim() == 2 and bias is not None:
  File "/home/caius/anaconda3/envs/Tutorials/lib/python3.8/site-packages/torch/nn/modules/module.py", line 575, in __getattr__
    raise AttributeError("'{}' object has no attribute '{}'".format(
AttributeError: 'Custom' object has no attribute 'dim'
</code></pre>
<p>I don’t know how am I supposed to declare a custom function or to alter the input data so as to make it work.<br>
Thanks and have a wonderful day! <img src="https://discuss.pytorch.org/images/emoji/apple/slight_smile.png?v=9" title=":slight_smile:" class="emoji" alt=":slight_smile:"></p>

username: sharvil
cooked: <p>I think you forgot to add <code>self.dim = dim</code> in <code>Custom.__init__</code>.</p>

username: caiusdebucean
cooked: <aside class="quote no-group quote-modified" data-username="caiusdebucean" data-post="1" data-topic="73174">
<div class="title">
<div class="quote-controls"></div>
<img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/caiusdebucean/48/21676_2.png" class="avatar"> caiusdebucean:</div>
<blockquote>
<p>class Custom(nn.Module): def <strong>init</strong>(self, weights = 1, dim = 1): super().<strong>init</strong>() self.weights = weights def forward(self, input): a = 2 x = input y = a + math.log(x) return y</p>
</blockquote>
</aside>
<p>Thanks for your reply. I’ve tried similar changes.<br>
Now it seems to show<br>
<code>TypeError: 'int' object is not callable</code></p>

username: ptrblck
cooked: <p>You would have to create instances of your <code>Custom</code> module before calling it (same as with other modules, e.g. <code>nn.Linear</code>).</p>
<p>Currently you are trying to pass the activation directly to the module instantiation:</p>
<pre><code class="lang-python">x = Custom(x)
</code></pre>
<p>Instead define instances of <code>Custom</code> in the <code>__init__</code> method of <code>Network</code> and call them in <code>forward</code>:</p>
<pre><code class="lang-python">class Network(nn.Module):
    def __init__(self):
        super().__init__()
        self.fc1 = nn.Linear(784, 128)
        self.fc2 = nn.Linear(128, 64)
        self.fc3 = nn.Linear(64, 10)
        self.custom = Custom(weights=1)
        
    def forward(self, x):
        x = self.custom(x)
        x = self.fc1(x)
        x = self.custom(x)
        x = self.fc2(x)
        x = self.custom(x)
        x = self.fc3(x)    
        return x
</code></pre>
<p>Note that this code will reuse the <code>self.custom</code> module.<br>
Since you don’t have any trainable parameters inside this module, this should be fine.</p>