def _cal_output_shape(height, width, kernel_shape, strides, pad):
	"""
	Args:
	  kernel_shape: [height, width]
	  strides: [height, width]
	  pad: 'SAME' or 'VALID'
	
	Returns:
	  output_shape: [output_h, output_w]
	"""
	# check the options of padding
	if (pad != 'SAME' and pad != 'VALID'):
		raise Exception("the option of padding must be either 'SAME' or 'VALID'")

	kernel_h, kernel_w = kernel_shape
	stride_h, stride_w = strides

	# calculate output_h
	if strides[0] == 1:
		if pad == 'SAME':
			output_h = height
		else:	# VALID
			output_h = height + kernel_h - 1
	elif strides[0] > 1:
		if pad == 'SAME':
			# output_h = (height - 1) * stride_h + kernel_h - 2 * pad_h
			# assuming padding is 1
			output_h = (height - 1) * stride_h + kernel_h - 2
		else:	# VALID 
			output_h = (height - 1) * stride_h + kernel_h
	else:
		raise ValueError

	# calculate output_w
	if strides[1] == 1:
		if pad == 'SAME':
			output_w = width
		else:	# VALID
			output_w = width + kernel_w - 1
	elif strides[1] > 1:
		if pad == 'SAME':
			output_w = (width - 1) * stride_w + kernel_w - 2
		else:	# VALID
			output_w = (width - 1) * stride_w + kernel_w
	else:
		raise ValueError
	
	return output_h, output_w