Reputation: 282
I am dealing with multi-Siemens CNN that consists of 3 sub-networks, the CNN takes 6 images as an input each 3 images represent a person. I labeled the data as following: 2000 pairs as positive and 2000 pairs as negative but I want to make sure that the batches are balanced as well, ex: 64 batch means 32 positive & 32 negative.
the model take 6 inputs of the following shape: (3024, 1, 192, 192) y_train shape = (1008, 1)
However when I tried to balance the batches the fit_gen expect an output of the following (x,y) and I need an output as the following (x[:0]..X[:5],y) to fit it in the model
The following error occurred
Output of generator should be a tuple `(x, y, sample_weight)` or `(x, y)`. Found: (array([[[[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
...,
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.]]],
I used the following formula to balance the batches:
img_1 = x_train[:, 0]
img_2 = x_train[:, 1]
img_3 = x_train[:, 2]
img_4 = x_train[:, 3]
img_5 = x_train[:, 4]
img_6 = x_train[:, 5]
gen = balanced_generator(x_train,img_1, img_2, img_3, img_4, img_5, img_6, y_train, 64)
modelMerged.fit_generator(gen, steps_per_epoch=1, epochs=epochs)
def balanced_generator(x,x1,x2,x3,x4,x5,x6, y, batch_size):
batch_x_shape = (batch_size, x.shape[1], x.shape[2], x.shape[3],x.shape[4])
batch_y_shape = (batch_size, )
batch_size1 = int(batch_size/2)
batch_x = np.ndarray(shape=batch_x_shape, dtype=x.dtype)
batch_y = np.zeros(shape=batch_y_shape, dtype=y.dtype)
for i in range(batch_size1):
ind1 = np.random.randint(0,y.shape[0])
while y[ind1] == 0:
ind1 = np.random.randint(0,y.shape[0])
batch_x[i,0,:,:,:] = x1[ind1,:,:,:]
batch_x[i,1,:,:,:] = x2[ind1,:,:,:]
batch_x[i,2,:,:,:] = x3[ind1,:,:,:]
batch_x[i,3,:,:,:] = x4[ind1,:,:,:]
batch_x[i,4,:,:,:] = x5[ind1,:,:,:]
batch_x[i,5,:,:,:] = x6[ind1,:,:,:]
batch_y[i] = y[ind1]
for i in range(batch_size):
i = int(batch_size/2)
ind2 = np.random.randint(0,y.shape[0])
while y[ind2] == 0:
ind2 = np.random.randint(0,y.shape[0])
batch_x[i,0,:,:,:] = x1[ind2,:,:,:]
batch_x[i,1,:,:,:] = x2[ind2,:,:,:]
batch_x[i,2,:,:,:] = x3[ind2,:,:,:]
batch_x[i,3,:,:,:] = x4[ind2,:,:,:]
batch_x[i,4,:,:,:] = x5[ind2,:,:,:]
batch_x[i,5,:,:,:] = x6[ind2,:,:,:]
batch_y[i] = y[ind2]
print("batch #")
yield(batch_x[:, 0],batch_x[:, 1],batch_x[:, 2],batch_x[:, 3],batch_x[:, 4],batch_x[:, 5], batch_y)
Upvotes: 1
Views: 645
Reputation: 3739
The fit_generator
in keras
only takes input as (X,Y)
format, so you should concate your X output in yield
part into a list
in your customized generator function :
yield( [batch_x[:, 0],batch_x[:, 1],batch_x[:, 2],batch_x[:, 3],batch_x[:, 4],batch_x[:, 5]], batch_y) # <- Add []
Upvotes: 1