PixelCNN on 1 Dimension

Hi,
I’m trying to modify PixelCNN model to work on 1D as well.
Let’s say i want the input of the network to be vector (size 20) and output a vector (size 60), I tried to play with the architecture to make it work but it didnt work.

First of all i changed to Conv2D to be 1D (the mask work on 1D now). but i dont understand how to make it train.

this is the architecture of the model:

class PixelCNN(nn.Module):
def __init__(self, no_layers=8, kernel = 7, channels=64, device=None, e_dim=16, z_dim=64):
	super(PixelCNN, self).__init__()
	self.no_layers = no_layers
	self.kernel = kernel
	self.channels = channels
	self.layers = {}
	self.device = device

	self.Conv2d_1 = MaskedCNN('A',1,channels, kernel, 1, kernel//2, bias=False)
	self.BatchNorm2d_1 = nn.BatchNorm2d(channels)
	self.ReLU_1= nn.ReLU(True)

	self.Conv2d_2 = MaskedCNN('B',channels,channels, kernel, 1, kernel//2, bias=False)
	self.BatchNorm2d_2 = nn.BatchNorm2d(channels)
	self.ReLU_2= nn.ReLU(True)

	self.Conv2d_3 = MaskedCNN('B',channels,channels, kernel, 1, kernel//2, bias=False)
	self.BatchNorm2d_3 = nn.BatchNorm2d(channels)
	self.ReLU_3= nn.ReLU(True)

	self.Conv2d_4 = MaskedCNN('B',channels,channels, kernel, 1, kernel//2, bias=False)
	self.BatchNorm2d_4 = nn.BatchNorm2d(channels)
	self.ReLU_4 = nn.ReLU(True)

	self.Conv2d_5 = MaskedCNN('B',channels,channels, kernel, 1, kernel//2, bias=False)
	self.BatchNorm2d_5 = nn.BatchNorm2d(channels)
	self.ReLU_5= nn.ReLU(True)

	self.Conv2d_6 = MaskedCNN('B',channels,channels, kernel, 1, kernel//2, bias=False)
	self.BatchNorm2d_6 = nn.BatchNorm2d(channels)
	self.ReLU_6= nn.ReLU(True)

	self.Conv2d_7 = MaskedCNN('B',channels,channels, kernel, 1, kernel//2, bias=False)
	self.BatchNorm2d_7 = nn.BatchNorm2d(channels)
	self.ReLU_7= nn.ReLU(True)

	self.Conv2d_8 = MaskedCNN('B',channels,channels, kernel, 1, kernel//2, bias=False)
	self.BatchNorm2d_8 = nn.BatchNorm2d(channels)
	self.ReLU_8= nn.ReLU(True)

	self.out = nn.Conv2d(channels, 256, 1)

MaskedCNN defined as:

class MaskedCNN(nn.Conv2d):
def __init__(self, mask_type, *args, **kwargs):
	self.mask_type = mask_type

	assert mask_type in ['A', 'B'], "Unknown Mask Type"
	super(MaskedCNN, self).__init__(*args, **kwargs)
	self.register_buffer('mask', self.weight.data.clone())

	_, depth, height, width = self.weight.size()
	self.mask.fill_(1)
	if mask_type =='A':
		self.mask[:,:,height//2,width//2:] = 0
		self.mask[:,:,height//2+1:,:] = 0
	else:
		self.mask[:,:,height//2,width//2+1:] = 0
		self.mask[:,:,height//2+1:,:] = 0


def forward(self, x):
	self.weight.data*=self.mask
	return super(MaskedCNN, self).forward(x)

Thanks :slight_smile:

1 Like

I just tested this network. But I didn’t try 1D version.
I think you should prepare your data at first.
For each iteration, feed the network data.
The network above use conv2d, change it to con1d.
The mask is also should be changed to a vector.
1D is not more complex than 2D problem.

Thanks.
I did it but im still struggling to do this. when i tested this network on MNIST the input tensor was [batch_size, 1, image_size, image_size] and the output tensor was [batch_size, 256, image_size, image_size].

if i want to pass tensor of vector of size 20 (i prepared the data) like [batch_size, 20] and then i want to use the same loss function (crossEntropy) i don’t understand how to do it.

Did you make it work? I need to do something similar with time series but I have the same problem.