text: import torch
  import torch.nn as nn
  from torch.autograd import Variable
  
  from collections import OrderedDict
  
  
  def summary(model, input_size, device="cpu"):
  	def register_hook(module):
  		def hook(module, input, output):
  			class_name = str(module.__class__).split('.')[-1].split("'")[0]
  			module_idx = len(summary)
  
  			m_key = '%s-%i' % (class_name, module_idx + 1)
  			summary[m_key] = OrderedDict()
  			summary[m_key]['input_shape'] = list(input[0].size())
  			summary[m_key]['input_shape'][0] = -1
  			if isinstance(output, (list, tuple)):
  				summary[m_key]['output_shape'] = [[-1] + list(o.size())[1:] for o in output]
  			else:
  				summary[m_key]['output_shape'] = list(output.size())
  				summary[m_key]['output_shape'][0] = -1
  
  			params = 0
  			if hasattr(module, 'weight') and hasattr(module.weight, 'size'):
  				params += torch.prod(torch.LongTensor(list(module.weight.size())))
  				summary[m_key]['trainable'] = module.weight.requires_grad
  			if hasattr(module, 'bias') and hasattr(module.bias, 'size'):
  				params += torch.prod(torch.LongTensor(list(module.bias.size())))
  			summary[m_key]['nb_params'] = params
  
  		if (not isinstance(module, nn.Sequential) and
  			    not isinstance(module, nn.ModuleList) and
  			    not (module == model)):
  			hooks.append(module.register_forward_hook(hook))
  
  	device = device.lower()
  	assert device in ["cuda", "cpu"], "Input device is not valid, please specify 'cuda' or 'cpu'"
  
  	if device == "cuda" and torch.cuda.is_available():
  		dtype = torch.cuda.FloatTensor
  	else:
  		dtype = torch.FloatTensor
  
  	# check if there are multiple inputs to the network
  	if isinstance(input_size[0], (list, tuple)):
  		x = [Variable(torch.rand(2, *in_size)).type(dtype) for in_size in input_size]
  	else:
  		x = Variable(torch.rand(2, *input_size)).type(dtype)
  
  	# print(type(x[0]))
  	# create properties
  	summary = OrderedDict()
  	hooks = []
  	# register hook
  	model.apply(register_hook)
  	# make a forward pass
  	# print(x.shape)
  	model(x)
  	# remove these hooks
  	for h in hooks:
  		h.remove()
  
  	print('----------------------------------------------------------------')
  	line_new = '{:>20}  {:>25} {:>15}'.format('Layer (type)', 'Output Shape', 'Param #')
  	print(line_new)
  	print('================================================================')
  	total_params = 0
  	trainable_params = 0
  	for layer in summary:
  		# input_shape, output_shape, trainable, nb_params
  		line_new = '{:>20}  {:>25} {:>15}'.format(layer, str(summary[layer]['output_shape']),
  		                                          '{0:,}'.format(summary[layer]['nb_params']))
  		total_params += summary[layer]['nb_params']
  		if 'trainable' in summary[layer]:
  			if summary[layer]['trainable'] == True:
  				trainable_params += summary[layer]['nb_params']
  		print(line_new)
  	print('================================================================')
  	print('Total params: {0:,}'.format(total_params))
  	print('Trainable params: {0:,}'.format(trainable_params))
  	print('Non-trainable params: {0:,}'.format(total_params - trainable_params))
  	print('----------------------------------------------------------------')
  
  	return summary