根据我之前的问题,我编写了这段代码来训练自动编码器,然后提取特性。(变量名称可能有一些更改)
# Autoencoder class
#https://medium.com/pytorch/implementing-an-autoencoder-in-pytorch-19baa22647d1
class AE_class(nn.Module):
def __init__(self, **kwargs):
super().__init__()
self.encoder_hidden_layer = nn.Linear(
in_features=kwargs["input_shape"], out_features=128
)
self.encoder_output_layer = nn.Linear(
in_features=128, out_features=128
)
self.decoder_hidden_layer = nn.Linear(
in_features=128, out_features=128
)
self.decoder_output_layer = nn.Linear(
in_features=128, out_features=kwargs["input_shape"]
)
def forward(self, features):
#print("in forward")
#print(type(features))
activation = self.encoder_hidden_layer(features)
activation = torch.relu(activation)
code = self.encoder_output_layer(activation)
code = torch.relu(code)
activation = self.decoder_hidden_layer(code)
activation = torch.relu(activation)
activation = self.decoder_output_layer(activation)
reconstructed = torch.relu(activation)
return reconstructed
def encode(self, features_h):
activation_h = self.encoder_hidden_layer(features_h)
activation_h = torch.relu(activation_h)
code_h = self.encoder_output_layer(activation_h)
code_h = torch.relu(code_h)
return code_h
然后,进行培训:
def retrieve_AE_features(X_before, n_voxel_region):
# use gpu if available
#https://discuss.pytorch.org/t/runtimeerror-tensor-for-out-is-on-cpu-tensor-for-argument-1-self-is-on-cpu-but-expected-them-to-be-on-gpu-while-checking-arguments-for-addmm/105453
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
# create a model from `AE` autoencoder class
# load it to the specified device, either gpu or cpu
model_AE = AE_class(input_shape=n_voxel_region).to(device)
# create an optimizer object
# Adam optimizer with learning rate 1e-3
optimizer = optim.Adam(model_AE.parameters(), lr=1e-3)
# mean-squared error loss
criterion = nn.MSELoss()
X_tensor = torch.tensor(X_before, dtype=torch.float32)
print(type(X_tensor))
train_loader = torch.utils.data.DataLoader(
X_tensor, batch_size=64, shuffle=True, num_workers=2, pin_memory=True
)
test_loader = torch.utils.data.DataLoader(
X_tensor, batch_size=32, shuffle=False, num_workers=2
)
print(type(train_loader))
for epoch in range(epochs_AE):
loss = 0
for batch_features in train_loader:
# reshape mini-batch data to [N, 784] matrix
# load it to the active device
#batch_features = batch_features.view(-1, 784).to(device)
#print(batch_features.shape)
# reset the gradients back to zero
# PyTorch accumulates gradients on subsequent backward passes
optimizer.zero_grad()
# compute reconstructions
outputs = model_AE(batch_features)
# compute training reconstruction loss
train_loss = criterion(outputs, batch_features)
# compute accumulated gradients
train_loss.backward()
# perform parameter update based on current gradients
optimizer.step()
# add the mini-batch training loss to epoch loss
loss += train_loss.item()
# compute the epoch training loss
loss = loss / len(train_loader)
# display the epoch training loss
print("AE, epoch : {}/{}, loss = {:.6f}".format(epoch + 1, epochs_AE, loss))
#After training
hidden_features = model_AE.encode(X_before)
return hidden_features
然而,我收到了以下错误:
参数#2"mat1"的张量在CPU上,但应在GPU上(检查addmm的参数时)
我的一些变量似乎应该以另一种方式定义,以便能够在GPU上执行。
我的问题:
- 我如何理解哪些变量将在GPU上执行,哪些变量在CPU上执行
- 如何修复?换句话说,如何定义GPU上可执行的变量
提前感谢
我看到您的型号已移动到设备,这由此行device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
决定。它可以是cpu
或cuda
。
所以添加这行batch_features = batch_features.to(device)
实际上会将您的输入数据移动到device
由于您的模型已移动到设备,因此您还应将输入移动到设备。以下代码有更改
for epoch in range(epochs_AE):
loss = 0
for batch_features in train_loader:
batch_features = batch_features.to(device) #this will move inout to your device
optimizer.zero_grad()
outputs = model_AE(batch_features)
train_loss = criterion(outputs, batch_features)
...
回答您的问题:调用.to(device)
可以直接将张量移动到您指定的设备
如果您想对其进行硬编码,请在torch
张量上执行.to('cpu')
或.to('cuda')