0
トーチにカスタムsoftmaxレイヤーを実装すると、CPUモードで非常にうまく動作しますが、GPUモードに変更すると機能しません。順方向および逆方向の繰り返しを行った後、CPUモードでは各エポックごとに減少します。Torch:私のカスタムレイヤーがGPUで動作しない
マイカスタムソフトマックス層は
local MySoftMax, Parent = torch.class('nn.MySoftMax', 'nn.Module')
function MySoftMax:__init()
Parent.__init(self)
end
--input = batch * 2 * 40 * 40 * 40
--output = batch * 1 * 40 * 40 * 40
function MySoftMax:updateOutput(input)
tmp_input = input:clone()
size_input = tmp_input:size()
self.output = torch.CudaTensor(size_input[1], 1, size_input[3], size_input[4], size_input[5])
exp_input = tmp_input:exp()
for i = 1, size_input[1] do
tmp_output = exp_input[i][1]:clone()
sum_exp_input = exp_input[i][1]:add(exp_input[i][2])
self.output[i][1] = tmp_output:cdiv(sum_exp_input)
end
return self.output
end
function MySoftMax:updateGradInput(input, gradOutput)
tmp_input = input:clone()
size_input = input:size()
self.gradInput = torch.CudaTensor(size_input[1], 2, size_input[3], size_input[4], size_input[5])
exp_input = tmp_input:exp()
for i = 1, size_input[1] do
tmp_exp_input = exp_input[i][1]:clone()
add_exp = exp_input[i][1]:add(exp_input[i][2])
pow_exp = add_exp:pow(2)
mul_exp = tmp_exp_input:cmul(exp_input[i][2])
self.gradInput[i][1] = mul_exp:cdiv(pow_exp)
self.gradInput[i][2] = self.gradInput[i][1]
self.gradInput[i][2] = -self.gradInput[i][1]
self.gradInput[i][1]:cmul(gradOutput[i][1])
self.gradInput[i][2]:cmul(gradOutput[i][1])
end
return self.gradInput
end
で、GPUのトレーニングコードは次のとおりです。
model = model:cuda()
criterion = criterion:cuda()
inputs = torch.CudaTensor(batch_size, 1, bbx_size, bbx_size, bbx_size)
targets = torch.CudaTensor(batch_size, 1, bbx_size, bbx_size, bbx_size)
model:training()
torch.manualSeed(train_size)
shuffle = torch.randperm(train_size)
print '==> epoch = '
print(epoch)
epoch_error = 0.0
for t = 1, train_size, batch_size do
xlua.progress(t, train_size)
for i = 1, batch_size do
inputs[i] = train_input[shuffle[t + i - 1]]
targets[i] = train_output[shuffle[t + i - 1]]
end
local feval = function(x)
gradParameters:zero()
outputs = model:forward(inputs)
err = criterion:forward(outputs, targets)
df_do = criterion:backward(outputs, targets)
model:backward(inputs, df_do)
epoch_error = epoch_error + err
return f, gradParameters
end
optim.sgd(feval, parameters, config)
end
私のモデルは次のとおりです。
cnn_state = {8, 16, 32, 64, 128}
pool_size = 2
filter_size = 2
batch_size = 64
model = nn.Sequential()
--stage 1
--1*40*40*40
model:add(nn.VolumetricConvolution(1, cnn_state[1], filter_size, filter_size, filter_size))
model:add(nn.ReLU())
--8*39*39*39
model:add(nn.VolumetricConvolution(cnn_state[1], cnn_state[2], filter_size, filter_size, filter_size))
model:add(nn.ReLU())
--16*38*38*38
maxpool1 = nn.VolumetricMaxPooling(pool_size, pool_size, pool_size, pool_size, pool_size, pool_size)
model:add(maxpool1)
--16*19*19*19
--stage 2
--16*19*19*19
model:add(nn.VolumetricConvolution(cnn_state[2], cnn_state[3], filter_size, filter_size, filter_size))
model:add(nn.ReLU())
--32*18*18*18
model:add(nn.VolumetricConvolution(cnn_state[3], cnn_state[4], filter_size + 1, filter_size + 1, filter_size + 1))
model:add(nn.ReLU())
--64*16*16*16
maxpool2 = nn.VolumetricMaxPooling(pool_size, pool_size, pool_size, pool_size, pool_size, pool_size)
model:add(maxpool2)
--64*8*8*8
--stage 3
model:add(nn.VolumetricConvolution(cnn_state[4],cnn_state[5], filter_size, filter_size, filter_size))
model:add(nn.ReLU())
--128*7*7*7
--deconvolution
model:add(nn.VolumetricFullConvolution(cnn_state[5], cnn_state[4], filter_size, filter_size, filter_size))
model:add(nn.ReLU())
--64*8*8*8
model:add(nn.VolumetricMaxUnpooling(maxpool2))
--64*16*16*16
model:add(nn.VolumetricFullConvolution(cnn_state[4], cnn_state[3], filter_size + 1, filter_size + 1, filter_size + 1))
model:add(nn.ReLU())
--32*18*18*18
model:add(nn.VolumetricFullConvolution(cnn_state[3], cnn_state[2], filter_size, filter_size, filter_size))
model:add(nn.ReLU())
--16*19*19*19
model:add(nn.VolumetricMaxUnpooling(maxpool1))
--16*38*38*38
model:add(nn.VolumetricFullConvolution(cnn_state[2], cnn_state[1], filter_size, filter_size, filter_size))
model:add(nn.ReLU())
--8*39*39*39
model:add(nn.VolumetricFullConvolution(cnn_state[1], 2, filter_size, filter_size, filter_size))
--2*40*40*40
model:add(nn.MySoftMax())
私のモデルでは、それはだCPUモードで正常に動作しますCudaTensorの代わりにTenserを使用すると、損失が減少し、予測が良くなります。 GPUモードでは動作しません。 私の問題は、私のカスタムレイヤの実装にあるかもしれないと思うかもしれません。多分GPUでは動作しません。 GPUでレイヤーを実装する際に注意が必要なことはありますか?または私のコードに何か問題がありますか?