I'm trying to freeze a layer of a toy model when training using Pytorch. In the following code, when I run the code on CPU, the layer isn't updated. (Please see the code line print("%.8f" % np.max(np.abs(before -after)))). However, when I run the code on GPU, the layer is updated. What is wrong with my implementation?
import torch
from torch import nn
from torch.autograd import Variable
import torch.nn.functional as F
import torch.optim as optim
import numpy as np
def toNP(x):
return x.detach().to('cpu').numpy()
# toy feed-forward net
class Sub_Net(nn.Module):
def __init__(self):
super(Sub_Net, self).__init__()
self.fc1 = nn.Linear(10, 3)
self.fc2 = nn.Linear(3, 3)
self.fc3 = nn.Linear(3, 3)
self.fc4 = nn.Linear(3, 3)
self.fc5 = nn.Linear(3, 1)
def forward(self, x):
x = self.fc1(x)
x = self.fc2(x)
x = self.fc3(x)
x = self.fc4(x)
x = self.fc5(x)
return x
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.Sub_Net = Sub_Net()
self.fc1 = nn.Linear(10, 3)
self.fc2 = nn.Linear(3, 3)
self.fc3 = nn.Linear(3, 3)
self.fc4 = nn.Linear(3, 3)
self.fc5 = nn.Linear(3, 1)
def forward(self, x):
y = self.Sub_Net(x)
x = self.fc1(x)
x = self.fc2(x)
x = self.fc3(x)
x = self.fc4(x)
x = self.fc5(x)
return x+y
def generator_step(net, optimizer, criterion, input, target):
output = net(input)
loss = criterion(output, target)
net.zero_grad()
loss.backward()
optimizer.step()
def discrimination_step(net, optimizer, criterion, input, target):
for param in net.Sub_Net.parameters():
param.requires_grad = False
before = toNP(net.Sub_Net.fc2.weight)
output = net(input)
loss = criterion(output, target)
net.zero_grad()
loss.backward()
optimizer.step()
after = toNP(net.Sub_Net.fc2.weight)
print("%.8f" % np.max(np.abs(before -after)) )
# Run model on GPU
# net = Net().type(torch.cuda.FloatTensor)
# random_input = Variable(torch.randn(10, )).cuda()
# random_target = Variable(torch.randn(1, )).cuda()
# Run model on CPU
net = Net()
random_input = Variable(torch.randn(10, ))
random_target = Variable(torch.randn(1, ))
# loss
criterion = nn.MSELoss()
optimizer = optim.Adam(filter(lambda p: p.requires_grad, net.parameters()), lr=0.1)
for epoch in range(1, 10):
generator_step(net, optimizer, criterion, random_input, random_target)
discrimination_step(net, optimizer, criterion, random_input, random_target)
Results when running on CPU
0.00000000
0.00000000
0.00000000
0.00000000
0.00000000
0.00000000
0.00000000
0.00000000
0.00000000
Results when running on GPU
0.06700575
0.04242781
0.03090768
0.02379489
0.01885229
0.01519108
0.01237211
0.01014686
0.00836059