Argument parser object does not contain attribute defined in parser - python

I am working on a program that works on hyperspectral image super-resolution by using Neural Networks, Now in here the Mains directory of the program contains multiple parsers. The parsers and subparsers seem to have been defined correctly
def main():
# parsers
main_parser = argparse.ArgumentParser(description="parser for SR network")
subparsers = main_parser.add_subparsers(title="subcommands", dest="subcommand")
train_parser = subparsers.add_parser("train", help="parser for training arguments")
train_parser.add_argument("--cuda", type=int, required=False,default=1,
help="set it to 1 for running on GPU, 0 for CPU")
train_parser.add_argument("--batch_size", type=int, default=32, help="batch size, default set to 64")
train_parser.add_argument("--epochs", type=int, default=40, help="epochs, default set to 20")
train_parser.add_argument("--n_feats", type=int, default=256, help="n_feats, default set to 256")
train_parser.add_argument("--n_blocks", type=int, default=3, help="n_blocks, default set to 6")
train_parser.add_argument("--n_subs", type=int, default=8, help="n_subs, default set to 8")
train_parser.add_argument("--n_ovls", type=int, default=2, help="n_ovls, default set to 1")
train_parser.add_argument("--n_scale", type=int, default=4, help="n_scale, default set to 2")
train_parser.add_argument("--use_share", type=bool, default=True, help="f_share, default set to 1")
train_parser.add_argument("--dataset_name", type=str, default="Chikusei", help="dataset_name, default set to dataset_name")
train_parser.add_argument("--model_title", type=str, default="SSPSR", help="model_title, default set to model_title")
train_parser.add_argument("--seed", type=int, default=3000, help="start seed for model")
train_parser.add_argument("--learning_rate", type=float, default=1e-4,
help="learning rate, default set to 1e-4")
train_parser.add_argument("--weight_decay", type=float, default=0, help="weight decay, default set to 0")
train_parser.add_argument("--save_dir", type=str, default="./trained_model/",
help="directory for saving trained models, default is trained_model folder")
train_parser.add_argument("--gpus", type=str, default="1", help="gpu ids (default: 7)")
test_parser = subparsers.add_parser("test", help="parser for testing arguments")
test_parser.add_argument("--cuda", type=int, required=False,default=1,
help="set it to 1 for running on GPU, 0 for CPU")
test_parser.add_argument("--gpus", type=str, default="0,1", help="gpu ids (default: 7)")
args = main_parser.parse_args()
os.environ['CUDA_VISIBLE_DEVICES'] = args.gpus
print(args.gpus)
if args.subcommand is None:
print("ERROR: specify either train or test")
sys.exit(1)
if args.cuda and not torch.cuda.is_available():
print("ERROR: cuda is not available, try running on CPU")
sys.exit(1)
if args.subcommand == "train":
train(args)
else:
test(args)
pass
however, upon using the args object, the compiler throws an error saying that the object has no attribute gpus. Though, the test parser does contain the attribute 'gpus'
"G:\Python projects\venv\Scripts\python.exe" "G:/Hyperspectral ISRO/SSPSR-master/mains.py"
Traceback (most recent call last):
File "G:\Hyperspectral ISRO\SSPSR-master\mains.py", line 309, in <module>
main()
File "G:\Hyperspectral ISRO\SSPSR-master\mains.py", line 70, in main
os.environ['CUDA_VISIBLE_DEVICES'] = args.gpus
AttributeError: 'Namespace' object has no attribute 'gpus'
I cannot figure out as to why this is happening, as I believe I am parsing the arguments correctly before using args, I tried to find similar issues on forums, but failed to do so.

All you need to do is:
args = main_parser.parse_args()
print(args) # for debugging help
if args.subcommand is None:
print("ERROR: specify either train or test")
sys.exit(1)
# now it's safe to reference `gpus` and `cuda` which are defined by both subparsers
os.environ['CUDA_VISIBLE_DEVICES'] = args.gpus
if args.cuda and not torch.cuda.is_available():
print("ERROR: cuda is not available, try running on CPU")
sys.exit(1)
if args.subcommand == "train":
train(args)
else:
test(args)
Just beware that train and test will get different args. train won't get any of the test values.
Try different command line values and note the differences in the args.
if you use
subparsers = main_parser.add_subparsers(title="subcommands", dest="subcommand",
required=True)
you don't need to do your own test for args.subcommand is None. The parser will do that for you.

Related

checkpoint_path and argparse error happend

def main(params):
# load the checkpoint
checkpoint_path = params['checkpoint_path']
max_images = params['max_images']
print ('loading checkpoint %s' % (checkpoint_path, ))
checkpoint = pickle.load(open(checkpoint_path, 'rb'))
checkpoint_params = checkpoint['params']
dataset = checkpoint_params['dataset']
model = checkpoint['model']
dump_folder = params['dump_folder']
...
...
...
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument('checkpoint_path', type=str, help='the input checkpoint')
parser.add_argument('-b', '--beam_size', type=int, default=1, help='beam size in inference. 1
indicates greedy per-word max procedure. Good value is approx 20 or so, and more = better.')
parser.add_argument('--result_struct_filename', type=str, default='result_struct.json',
help='filename of the result struct to save')
parser.add_argument('-m', '--max_images', type=int, default=-1, help='max images to use')
parser.add_argument('-d', '--dump_folder', type=str, default="", help='dump the relevant images to
a separate folder with this name?')
args = parser.parse_args()
params = vars(args) # convert to ordinary dict
print ('parsed parameters:')
print (json.dumps(params, indent = 2))
main(params)
I fix parser.add_argument('-checkpoint_path', type=str, help='the input checkpoint')
and next problem showed up in checkpoint_path = params['checkpoint_path'].
I tried to putting a file like D:\neuraltalk\cv\model_checkpoint_flickr8k_DESKTOP-4PPS67A_baseline_26.76.p
but it doesn't work...
please help me
I solve this problem on my own.
just changed a line of code
checkpoint_path = 'D:\\neuraltalk\cv\\model_checkpoint_flickr8k_DESKTOP-4PPS67A_baseline_17.10.p'

passing a dict with arguments to argparse

I am using a codebase that expects a large set of argument via command line using argparse library and I neet to call that code inside a loop and inject the arguments via dictionary and not via command line without changing that codebase, I call the code as follow:
parser = argparse.ArgumentParser('Training', parents=[get_args_parser()])
args = parser.parse_args()
main(args)
Where get_args_parser() is a large list of arguments and defaults such as :
def get_args_parser():
parser = argparse.ArgumentParser('Set transformer detector', add_help=False)
parser.add_argument('--lr', default=1e-4, type=float)
parser.add_argument('--lr_backbone', default=1e-5, type=float)
parser.add_argument('--batch_size', default=2, type=int)
parser.add_argument('--weight_decay', default=1e-4, type=float)
parser.add_argument('--epochs', default=300, type=int)
parser.add_argument('--lr_drop', default=200, type=int)
...
If i need to pass a dictionary , as arguments , like:
argdict = {'lr_drop':20,'batch_size':5}
How can I do it?
you should use like this:
import argparse
ap = argparse.ArgumentParser()
ap.add_argument("-d", "--dict", required=True, help="Your dict as string", default="{}")
args = vars(ap.parse_args())
argdict = eval(args["dict"])
print(argdict)
# or you cam print some dict specific var
print(argdict["name"]) #Jasar
the you can call your file like it:
python3 file.py -d '{"name":"Jasar"}'
using some clues by #Jaser and #chepner , what i did is as follow:
args_to_argdict = {'a':1 , 'b':49 ,'c': 'text' }
parser = argparse.ArgumentParser(parents=[get_args_parser()])
args = parser.parse_args()
arg_dict = vars(args)
for key,value in args_to_argdict.items():
arg_dict[key]= value
so that the args value change , then i run the main :
main(args)
with the modified args .

saving arguments with ArgumentParser in a dictionary

i obtain different arguments from command lines:
def get_args():
parser = ArgumentParser(description='neural network project')
parser.add_argument('--epochs', type=int, default=150)
parser.add_argument('--decay_epoch', type=int, default=100)
parser.add_argument('--batch_size', type=int, default=1)
parser.add_argument('--lr', type=float, default=.0002)
parser.add_argument('--load_height', type=int, default=286)
parser.add_argument('--load_width', type=int, default=286)
args = parser.parse_args()
return args
I would like to save all the argument obtained from get_args in a dictionary (to save then in a file .json or in a .txt).
argparse.ArgumentParser.parse_args returns an argparse.Namespace object, which is trivial to turn into a dict. Straight from the documentation:
This class is deliberately simple, just an object subclass with a
readable string representation. If you prefer to have dict-like view
of the attributes, you can use the standard Python idiom, vars():
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo')
>>> args = parser.parse_args(['--foo', 'BAR'])
>>> vars(args)
{'foo': 'BAR'}
Create a dictionary and add them by parser keyword.
neural_dict = {}
neural_dict['EPOCHS'] = args.epochs
neural_dict['DECAY_EPOCH'] = args.decay_epoch
.
.
.
To add to dictionary using a for loop:
neural_dict = {}
parser = argparse.ArgumentParser(description='neural network project')
parser.add_argument('--epochs', type=int, default=150)
parser.add_argument('--decay_epoch', type=int, default=100)
parser.add_argument('--batch_size', type=int, default=1)
parser.add_argument('--lr', type=float, default=.0002)
parser.add_argument('--load_height', type=int, default=286)
parser.add_argument('--load_width', type=int, default=286)
args = parser.parse_args()
#chepner is right...use his method instead
neural_dict = vars(args)

pass values from argparse to different methods

I have an issue with argparse. I pass different values from prompt with argparse and I want to use them with different functions. How should I arrange my code?
So far the issue is that when the method split_dataset is called the program stacks
def split_dataset(destpath):
start = t.clock()
load_atomrefs(os.path.join(destpath, 'atomref.npz'))
load_data(os.path.join(destpath, 'qm9.db'))
total_time = (t.clock()-start)
print(f"Download of DataSet Completed in {total_time}s")
def params_initialization(train_batch,test_batch,lr,**kwargs):
parameters = {'train_batch' : train_batch, 'test_batch' : test_batch, 'lr' : lr }
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.set_defaults(method = split_dataset)
parser.add_argument('--destpath', help='Path to QM9 directory')
parser.add_argument('--train_batch', type=int, help='Batch size for training', default=32)
parser.add_argument('--test_batch', type=int, help='Batch size for testing',default=32)
parser.add_argument('--lr', type=float, help='Learning rate',
default=1e-3)
parser.add_argument('--ntrain', help='Number of training examples',
type=int, default=-1)
parser.add_argument('--nval', help='Number of validation examples',
type=int, default=-1)
args = parser.parse_args()
if not os.path.exists(args.destpath):
os.makedirs(args.destpath)
args.method(**vars(args))
Use parser.add_argument_group and add call the group arguments in another function
def function_to_call_group(parser_group):
parser_group.add_argument(--argument)
if __name__ == '__main__':
parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
group1 = parser.add_argument_group("Group1")
function_to_call_group(group1)
# add other arguments to parser
args = parser.parse_args()

argpase requiring additional options if a specific option is selected

I have read many help links on this issue but none were EXACTLY like my situation so I decided to post here. I am using argparse to grab some command line options. The issue I am having is 1 flag is always required (-m) so I defined it as so
parser.add_argument('-m','--mode', type=str, required=True , metavar='<add|del|list|delID>', choices=['add', 'del' , 'list', 'delID'])
As you can see the only possible acceptable parameters are 'add', 'del', 'list' and delID'
What I need it to do is force 2 additional options to be required if a certain option is entered from the args.mode flag. Here's what I have tried currently but the error is always being triggered
parser = argparse.ArgumentParser(description='Help Desk Calendar Tool')
parser.add_argument('-m','--mode', type=str, required=True , metavar='<add|del|list|delID>', choices=['add', 'del' , 'list', 'delID'])
parser.add_argument('-s', '--start', type=str, required=False, metavar='<Start date in the following format - YYYY-MM-DD>')
parser.add_argument('-e','--end', type=str, required=False, metavar='<End date in the following format - YYYY-MM-DD>')
parser.add_argument('-d','--delete', type=str, required=False, metavar='<Event ID Here>')
args = parser.parse_args()
if args.mode in ('add','del','list'):
print args.mode
if args.start is None or args.end is None:
parser.error('Options add, del and list all require the start (-s) and end (-e) date to be set')
if args.mode in ('delID'):
if args.start is not None or args.end is not None:
parser.error('The option delID can ONLY except the event ID, no other options can be entered')
if args.mode in ('delID'):
if args.delete is None:
parser.error('The delete (-d) option is required when delID mode is selected')
So if I run command.py -s 2016-02-11 -e 2016-02-16 -m add the first error condition is still triggered.
Now it does work for the delID conditional checks. Any suggestions?
Thanks
Update
Looks like the above does in fact work. Turns out I had an additional error check in my definition that was throwing the error
if mode in ('add','del','list'):
parser.error("Options add,del and list all require a start (-s) and end (-e) date!")
Thanks for bringing it to my attention
Completed working code
def get_args():
parser = argparse.ArgumentParser(description='Help Desk Calendar Tool')
parser.add_argument('-m','--mode', type=str, required=True , metavar='<add|del|list|delID>', choices=['add', 'del' , 'list', 'delID'])
parser.add_argument('-s', '--start', type=str, required=False, metavar='<Start date in the following format - YYYY-MM-DD>')
parser.add_argument('-e','--end', type=str, required=False, metavar='<End date in the following format - YYYY-MM-DD>')
parser.add_argument('-d','--delete', type=str, required=False, metavar='<Event ID Here>')
args = parser.parse_args()
if args.mode in ['add','del','list']:
if args.start is None or args.end is None:
parser.error('Options add, del and list all require the start (-s) and end (-e) date to be set')
if args.mode == 'delID':
if args.start is not None or args.end is not None:
parser.error('The option delID can ONLY except the event ID, no other options can be entered')
if args.mode == 'delID':
if args.delete is None:
parser.error('The delete (-d) option is required when delID mode is selected')
start = args.start
end = args.end
mode = args.mode
event = args.delete
return start,end,mode,event

Categories

Resources