Thank you in advance.
I have been trying to turn a binary classifier into a seq-to-10classifier, where tokenized DNA sequence (variable length k-mers) e.g. “ATG A T A C” would have a predicted output class from {0,1,2,3,…9}.
The issue is that I am working with batches of size 512, but when I set the number of classes in the predict function of the lstm model to 10 or 2 or whatever number I simply get:
Expected input batch_size (2) to match target batch_size (512).
In the training loop, even when I hidden.squeeze(), in my forward method:
	def forward( self, seq ):

		try:
			output, (hidden,_) 	= self.encoder(self.embedding(seq))
			# @20201120 - below is before, and the not commented one below that is how it is according ot the book
			#preds 				= self.predictor(hidden[-1].squeeze(0))  # e.g. remove 1D entries from the shape of an array, see: https://docs.scipy.org/doc/numpy/reference/generated/numpy.squeeze.html
			preds 				= self.predictor(hidden.squeeze(0))  # e.g. remove 1D entries from the shape of an array, see: https://docs.scipy.org/doc/numpy/reference/generated/numpy.squeeze.html

		except Exception as ex:
			print(ex)
			[max(seq[i]) for i in range(seq.shape[0])]
			pdb.set_trace()

		return preds

The full training function is here:
def training( epochs, model, optimizer, criterion, train_iterator, valid_iterator ):

	"""

	USAGE:
		MODEL 		= LSTMClassifier( HIDDEN_SIZE, INPUT_SIZE, VOCAB_SIZE )
		OPTIMIZER 	= optim.Adam(model.parameters(), lr=2e-2)  	# for e.g. of model, see: "class LSTMClassifier", lr is learning_rate
		CRITERION 	= nn.CrossEntropyLoss() 					# loss calculation choice, for strictly binary try CTRL+F: "BCE on page 83 of PyTorch for Deep Learning - O'Reilly"
		train( N_EPOCHS, MODEL, OPTIMIZER, CRITERION, train_iterator, valid_iterator )

	"""

	for epoch in range(1, epochs+1):

		training_loss 	= 0.0 # restart
		valid_loss 		= 0.0 # ^

		#
		# Training set learning
		#
		model.train() 	# recursion? or is this a method within LSTMClassifier

		#pdb.set_trace()

		for batch_idx, batch in enumerate(train_iterator):

			#pdb.set_trace()

			#model.zero_grad() 						# 1. restart [the gradients (?)]

			optimizer.zero_grad() 						# 1. restart [the gradients (?)]

			predict = model( batch.sequence )

			# if len(predict.shape)==2: # if num_layers = 1, then we wrap it in a list else, later we get slicing errors
			# 	#print("Layers is 1")
			# 	predict = [model( batch.sequence )] 			# 2. predict [the output labels]
			# 	#pdb.set_trace()
			# else:
			# 	pass
			
			#pdb.set_trace()

			####################

			## machine test layer 0 

			pdb.set_trace() ## @20201120 - debugging - expected input batch+size (2) to match target batch_size (512) @LATEST

			loss = criterion( predict, batch.label )# 3. loss [check mistaken predictions via criterion]

			# }} // {{ 

			# ## machine test layer 1
			# loss = criterion( predict[-1], batch.label )# 3. loss [check mistaken predictions via criterion]

			####################

			loss.backward() 						# 4. backward [backpropagate to learn from mistakes]
			optimizer.step() 						# 5. optimise [the gradient changes to given learning rate]

			training_loss += loss.data.item() * batch.sequence.size(0) # accumulate losses for summary prints

		training_loss /= len(train_iterator) # account for the size of dataset

		model.eval() # @TODO: wtf?

		#
		# Validation set learning
		#
		correct = 0
		total 	= 0
		for batch_idx, batch in enumerate(valid_iterator):

			predict = model( batch.sequence ) 				# 1. prediction
			
			# if len(predict.shape)==2: # if num_layers = 1, then we wrap it in a list else, later we get slicing errors
			# 	#print("Layers is 1")
			# 	predict = [model( batch.sequence )] 			# 2. predict [the output labels]
			# 	#pdb.set_trace()
			# else:
			# 	pass


			####################

			## machine layer 0 - when num_layers = 2
			loss = criterion( predict, batch.label ) 	# 2. loss 

			# }} // {{

			# ## machine layer n - when num_layers = 2
			# loss = criterion( predict[-1], batch.label ) 	# 2. loss 
		
			####################

			valid_loss += loss.data.item() * batch.sequence.size(0) 	#  accumulate losses for validation set

			## neater
			# accuracy updates

			####################

			## machine test layer 0 - when num_layers = 2
			preds 	= predict.data.max(1, keepdim=True)[1]  # getting all predicted output classes for entire batch as a vector

			# }} // {{ 

			# ## machine test layer n - when num_layers = 2
			# preds 	= predict[-1].data.max(1, keepdim=True)[1]  # getting all predicted output classes for entire batch as a vector

			####################


			# ## default - when num_layers = 1 
			# preds 	= predict.data.max(1, keepdim=True)[1]  # getting all predicted output classes for entire batch as a vector
			# correct += float(preds.eq(batch.label.data.view_as(preds)).cpu().sum()) # compare predictions to actual validation set class outputs, and sums the correct answers
			
			#######################

			## machine test layer 0  - when num_layers = 2
			# accuracy updates
			correct += float(predict.data.max(1, keepdim=True)[1].eq(batch.label.data.view_as(predict.data.max(1, keepdim=True)[1])).cpu().sum())

			# }} // {{ 

			# ## machine test layer n  - when num_layers = 2
			# # accuracy updates
			# correct += float(predict[-1].data.max(1, keepdim=True)[1].eq(batch.label.data.view_as(predict[-1].data.max(1, keepdim=True)[1])).cpu().sum())

			#######################			

			total += len(preds)

		valid_loss /= len(valid_iterator)
		accuracy = (correct/total)*100.0

		#
		# Validation set learning
		#
		print("Epoch: {}, Training Loss: {:.2f}, Validation Loss: {:.2f}, Accuracy: {:.2f}%".format( 	epoch, 
																					training_loss, 
																					valid_loss,
																					accuracy) )