Lỗi TypeError: 'module' object is not callable

Mọi người cho e hỏi với, e chạy trong file main với hai dòng code như sau. File main của e 1 function từ 1 file module khác với directory được trích dẫn như dưới đây.

from conv_qsar_fast.main.core import build_model
model = build_model(**kwargs)

File module với function build_model được định nghĩa như dưới đây:

def build_model(embedding_size = 512, lr = 0.01, optimizer = 'adam', depth = 2, 
	scale_output = 0.05, padding = True, hidden = 0, hidden2 = 0, loss = 'mse', hidden_activation = 'tanh',
	output_activation = 'linear', dr1 = 0.0, dr2 = 0.0, output_size = 1, sum_after = False,
	molecular_attributes = False, use_fp = None, inner_rep = 32, verbose = False ):
	'''Generates simple embedding model to use molecular tensor as
	input in order to predict a single-valued output (i.e., yield)

	inputs:
		embedding_size - size of fingerprint for GraphFP layer
		lr - learning rate to use (train_model overwrites this value)
		optimizer - optimization function to use
		depth - depth of the neural fingerprint (i.e., radius)
		scale_output - initial scale for output weights in GraphFP
		padding - whether or not molecular tensors will be padded (i.e., batch_size > 1)
		hidden - number of hidden tanh nodes after FP (0 is linear)
		hidden2 - number of hidden nodes after "hidden" layer
		hidden_activation - activation function used in hidden layers
		output_activation - activation function for final output nodes
		dr1 - dropout rate after embedding
		dr2 - dropout rate after hidden
		loss - loss function as a string (e.g., 'mse')
		sum_after - whether to sum neighbor contributions after passing
					through a single network layer, or to do so before
					passing them from the network layer (during updates)
		molecular_attributes - whether to include additional molecular 
					attributes in the atom-level features (recommended)
		use_fp - whether the representation used is actually a fingerprint
					and not a convolutional network (for benchmarking)

	outputs:
		model - a Keras model'''

	
	

	# Base model
	if type(use_fp) == type(None):
		F_atom, F_bond = sizeAttributeVectors(molecular_attributes = molecular_attributes)
		mat_features = Input(shape = (None, F_atom), name = "featureMatrix")
		mat_adjacency = Input(shape = (None, None), name = "adjacencySelfMatrix")
		mat_specialbondtypes = Input(shape = (None, F_bond), name = "specialBondTypes")

		# Lists to keep track of keras features
		all_mat_features = [mat_features]
		contribs_by_atom = []
		actual_contribs_for_atoms = []
		actual_bond_contribs_for_atoms = []
		output_contribs_byatom = []
		output_contribs = []
		unactivated_features = []


		sum_across_atoms       = lambda x: K.sum(x, axis = 1)
		sum_across_atoms_shape = lambda x: (x[0], x[2])

		# Performs B * A where A has dimension (N_atoms, F_atom) and B has dimensions (N_atom, N_atom)
		mult_features_and_adj       = lambda x: K.batch_dot(x[1], x[0])
		mult_features_and_adj_shape = lambda x: (x[0][0], x[1][1], x[0][2],)

		for d in range(0, depth + 1):
			if verbose: print('### DEPTH {}'.format(d))

			# Get the output contribution using all_mat_features[d]
			if verbose: print('KERAS SHAPE OF ALL_MAT_FEATURES[d]')
			if verbose: print(all_mat_features[d]._keras_shape)
			if verbose: print('K.ndim of all_mat_features')
			if verbose: print(K.ndim(all_mat_features[d]))
			output_contribs_byatom.append(
				TimeDistributed(
					Dense(embedding_size, activation = 'softmax'),
					name = 'd{}_is_out'.format(d),
				)(all_mat_features[d])
			)
			if verbose: print('Added depth {} output contribution (still atom-wise)'.format(d))

			output_contribs.append(
				Lambda(sum_across_atoms, output_shape = sum_across_atoms_shape, name = "d{}_out_sum_across_atoms".format(d))(
					output_contribs_byatom[d]
				)
			)
			if verbose: print('Added depth {} output contribution (summed across atoms)'.format(d))

			# Update if needed
			if d != depth:

				contribs_by_atom.append(
					TimeDistributed(
						Dense(inner_rep, activation = 'linear'), 
						name = "d{}_atom_to_atom".format(d),
					)(all_mat_features[d])
				)
				if verbose: print('Calculated new atom features for each atom, d {}'.format(d))
				if verbose: print('ndim: {}'.format(K.ndim(contribs_by_atom[-1])))


				actual_contribs_for_atoms.append(
					merge(
						[contribs_by_atom[d], mat_adjacency], 
						mode = mult_features_and_adj,
						output_shape = mult_features_and_adj_shape,
						name = "d{} multiply atom contribs and adj mat".format(d)
					)
				)
				if verbose: print('Multiplied new atom features by adj matrix, d = {}'.format(d))
				if verbose: print('ndim: {}'.format(K.ndim(actual_contribs_for_atoms[-1])))

				actual_bond_contribs_for_atoms.append(
					TimeDistributed(
						Dense(inner_rep, activation = 'linear', use_bias = False),
						name = "d{} get bond contributions to new atom features".format(d),
					)(mat_specialbondtypes)
				)
				if verbose: print('Calculated bond effects on new atom features d = {}'.format(d))
				if verbose: print('ndim: {}'.format(K.ndim(actual_bond_contribs_for_atoms[-1])))

				unactivated_features.append(
					merge(
						[actual_contribs_for_atoms[d], actual_bond_contribs_for_atoms[d]], 
						mode = 'sum', 
						name = 'd{} combine atom and bond contributions to new atom features'.format(d),
					)
				)
				if verbose: print('Calculated summed features, unactivated, for d = {}'.format(d))
				if verbose: print('ndim: {}'.format(K.ndim(unactivated_features[-1])))

				all_mat_features.append(
					Activation(hidden_activation, name = "d{} inner update activation".format(d))(unactivated_features[d])
				)
				if verbose: print('Added activation layer for new atom features, d = {}'.format(d))
				if verbose: print('ndim: {}'.format(K.ndim(all_mat_features[-1])))

		if len(output_contribs) > 1:
			FPs = merge(output_contribs, mode = 'sum', name = 'pool across depths')
		else:
			FPs = output_contribs[0]

	else:
		FPs = Input(shape = (512,), name = "input fingerprint")

	# # Are we using a convolutional embedding or a fingerprint representation?
	# if type(use_fp) == type(None): # normal mode, use convolution
	# 	model.add(GraphFP(embedding_size, sizeAttributeVector(molecular_attributes) - 1, 
	# 		depth = depth,
	# 		scale_output = scale_output,
	# 		padding = padding,
	# 		activation_inner = 'tanh'))
	# 	print('    model: added GraphFP layer ({} -> {})'.format('mol', embedding_size))


	if hidden > 0:
		h1 = Dense(hidden, activation = hidden_activation)(FPs)
		h1d = Dropout(dr1)(h1)
		if verbose: print('    model: added {} Dense layer (-> {})'.format(hidden_activation, hidden))
		if hidden2 > 0:
			h2 = Dense(hidden2, activation = hidden_activation)(h1)
			if verbose: print('    model: added {} Dense layer (-> {})'.format(hidden_activation, hidden2))
			h = Dropout(dr2)(h2)
		else:
			h = h1d
	else:
		h = FPs

	ypred = Dense(output_size, activation = output_activation)(h)
	if verbose: print('    model: added output Dense layer (-> {})'.format(output_size))



	if type(use_fp) == type(None):
		model = Model(input = [mat_features, mat_adjacency, mat_specialbondtypes], 
			output = [ypred])
	else:
		model = Model(input = [FPs], 
			output = [ypred])

	if verbose: model.summary()

	# Compile
	if optimizer == 'adam':
		optimizer = Adam(lr = lr)
	elif optimizer == 'rmsprop':
		optimizer = RMSprop(lr = lr)
	elif optimizer == 'adagrad':
		optimizer = Adagrad(lr = lr)
	elif optimizer == 'adadelta':
		optimizer = Adadelta()
	else:
		print('Unrecognized optimizer')
		quit(1)

	# Custom loss to filter out NaN values in multi-task predictions
	if loss == 'custom':
		loss = mse_no_NaN
	elif loss == 'custom2':
		loss = binary_crossnetropy_no_NaN

	if verbose: print('compiling...',)
	model.compile(loss = loss, optimizer = optimizer)
	if verbose: print('done')

	return model

Github source: https://github.com/connorcoley/conv_qsar_fast

Em thử search các cách sửa lỗi khác nhau nhưng hầu hết đều nói rằng do tên module bị trùng với tên của function. Tuy nhiên e đã check kỹ càng là tên file module là core.py và không hề trùng với tên function. Xin các cao nhân cho ý kiến ạ?

P/s: File main trong link github là main_cv.py và file module là trong folder inputs, core.py

83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?