如何更简单方便的定义pytorch fullyconnect模型?
How to define pytorch fullyconnect model more simple and convenient?
我是pytorch初学者,想用Pytorch搭建一个全连接模型;
模型非常简单,如:
def forward(self, x):
x = self.relu(self.fc1(x))
x = self.relu(self.fc2(x))
return self.fc3(x)
但是当我想添加一些层或调整隐藏层时,我发现我必须写很多冗余代码,例如:
def forward(self, x):
x = self.relu(self.fc1(x))
x = self.relu(self.fc2(x))
x = self.relu(self.fc3(x))
x = self.relu(self.fc4(x))
x = self.relu(self.fc5(x))
...
return self.fcn(x)
此外,如果我想改变某些层的特征数,我必须改变相邻的层
所以我想知道一种更优雅的方法(可能更像pythonic并且更容易调整超参数)。
我尝试编写如下代码:
def __init__(self):
super().__init__()
self.hidden_num = [2881, 5500, 2048, 20] # i just want to change here! to try some new structure
self.fc = [nn.Linear(self.hidden_num[i], self.hidden_num[i + 1]).to(DEVICE) for i in range(len(self.hidden_num) - 1)]
self.relu = nn.ReLU()
def forward(self, x):
for i in range(len(self.fc)):
x = self.fc[i](x)
if i != (len(self.fc) - 1):
x = self.relu(x)
return x
但是我发现这种方式不行,模型建不出来
哪位兄弟能告诉我,如何定义一个像上面那样的全连接模型??
(所以我只能通过调整名为hidden_num的列表来调整模型层)
如果你想保持相同的方法,那么你可以使用 nn.ModuleList
在模块的 __init__
:
中正确注册所有线性层
class Model(nn.Module):
def __init__(self, hidden_num=[2881, 5500, 2048, 20]):
super().__init__()
self.fc = nn.ModuleList([
nn.Linear(hidden_num[i], hidden_num[i+1])
for i in range(len(hidden_num) - 1)])
def forward(self, x):
for i, m in enumerate(self.fc.children()):
x = m(x)
print(i)
if i != len(self.fc) - 1:
x = torch.relu(x)
return x
但是,您可能希望处理 __init__
函数中的逻辑 once。一种替代方法是使用 nn.Sequential
.
class Model(nn.Module):
def __init__(self, hidden_num=[2881, 5500, 2048, 20]):
super().__init__()
fc = []
for i in range(len(hidden_num) - 1):
fc.append(nn.Linear(hidden_num[i], hidden_num[i+1]))
if i != len(self.fc) - 1:
fc.append(nn.ReLU())
self.fc = nn.Sequential(fc)
def forward(self, x):
x = self.fc(x)
return x
理想情况下,您可以直接继承 nn.Sequential
以避免重写在这种情况下不必要的前向函数:
class Model(nn.Sequential):
def __init__(self, hidden_num=[2881, 5500, 2048, 20]):
fc = []
for i in range(len(hidden_num) - 1):
fc.append(nn.Linear(hidden_num[i], hidden_num[i+1]))
if i != len(self.fc) - 1:
fc.append(nn.ReLU())
super().__init__(fc)
我是pytorch初学者,想用Pytorch搭建一个全连接模型;
模型非常简单,如:
def forward(self, x):
x = self.relu(self.fc1(x))
x = self.relu(self.fc2(x))
return self.fc3(x)
但是当我想添加一些层或调整隐藏层时,我发现我必须写很多冗余代码,例如:
def forward(self, x):
x = self.relu(self.fc1(x))
x = self.relu(self.fc2(x))
x = self.relu(self.fc3(x))
x = self.relu(self.fc4(x))
x = self.relu(self.fc5(x))
...
return self.fcn(x)
此外,如果我想改变某些层的特征数,我必须改变相邻的层
所以我想知道一种更优雅的方法(可能更像pythonic并且更容易调整超参数)。
我尝试编写如下代码:
def __init__(self):
super().__init__()
self.hidden_num = [2881, 5500, 2048, 20] # i just want to change here! to try some new structure
self.fc = [nn.Linear(self.hidden_num[i], self.hidden_num[i + 1]).to(DEVICE) for i in range(len(self.hidden_num) - 1)]
self.relu = nn.ReLU()
def forward(self, x):
for i in range(len(self.fc)):
x = self.fc[i](x)
if i != (len(self.fc) - 1):
x = self.relu(x)
return x
但是我发现这种方式不行,模型建不出来
哪位兄弟能告诉我,如何定义一个像上面那样的全连接模型??
(所以我只能通过调整名为hidden_num的列表来调整模型层)
如果你想保持相同的方法,那么你可以使用 nn.ModuleList
在模块的 __init__
:
class Model(nn.Module):
def __init__(self, hidden_num=[2881, 5500, 2048, 20]):
super().__init__()
self.fc = nn.ModuleList([
nn.Linear(hidden_num[i], hidden_num[i+1])
for i in range(len(hidden_num) - 1)])
def forward(self, x):
for i, m in enumerate(self.fc.children()):
x = m(x)
print(i)
if i != len(self.fc) - 1:
x = torch.relu(x)
return x
但是,您可能希望处理 __init__
函数中的逻辑 once。一种替代方法是使用 nn.Sequential
.
class Model(nn.Module):
def __init__(self, hidden_num=[2881, 5500, 2048, 20]):
super().__init__()
fc = []
for i in range(len(hidden_num) - 1):
fc.append(nn.Linear(hidden_num[i], hidden_num[i+1]))
if i != len(self.fc) - 1:
fc.append(nn.ReLU())
self.fc = nn.Sequential(fc)
def forward(self, x):
x = self.fc(x)
return x
理想情况下,您可以直接继承 nn.Sequential
以避免重写在这种情况下不必要的前向函数:
class Model(nn.Sequential):
def __init__(self, hidden_num=[2881, 5500, 2048, 20]):
fc = []
for i in range(len(hidden_num) - 1):
fc.append(nn.Linear(hidden_num[i], hidden_num[i+1]))
if i != len(self.fc) - 1:
fc.append(nn.ReLU())
super().__init__(fc)