I think the key is to use Parameter instead of Variable.
Then l shows up in model.parameters() (but not in model.state_dict(), but I’m not sure it’s supposed to).
>>> import torch
>>> from torch.autograd import Variable
>>> from torch.nn import Parameter
>>>
>>> #  Learnable softshrink func
... def softshrink(x, lambd):
...     mask1 = x > lambd
...     mask2 = x < -lambd
...     out = torch.zeros_like(x)
...     out += mask1.float() * -lambd + mask1.float() * x
...     out += mask2.float() * lambd + mask2.float() * x
...     return out
...
>>> # A Neural Network
... class LISTA(torch.nn.Module):
...     def __init__(self, D_in, D_out):
...         super(LISTA, self).__init__()
...         self.We = torch.nn.Linear(D_in, D_out)
...         self.S = torch.nn.Linear(D_out, D_out)
...         self.l = Parameter(torch.Tensor([0.5]))
...     def forward(self, x):
...         out = softshrink(self.We(x),self.l)
...         for i in range(20):
...             out = softshrink(self.We(x)+self.S(out),self.l)
...         out = nn.functional.sigmoid(out)
...         return out
...
>>> model = LISTA(1, 1)
>>> list(model.parameters())
[Parameter containing:
 0.5000
[torch.FloatTensor of size 1]
, Parameter containing:
 0.6897
[torch.FloatTensor of size 1x1]
, Parameter containing:
-0.3733
[torch.FloatTensor of size 1]
, Parameter containing:
 0.4282
[torch.FloatTensor of size 1x1]
, Parameter containing:
-0.5218
[torch.FloatTensor of size 1]
]