linux指令与python模型训练日志、配置相关问题

  • Linux

    1. 查看服务器上的进程
      ps -u(当前用户的程序)
      ps -au(所有用户的程序)
      前面两个够用了
      ps -a服务器上的所有程序
      ps -x所有程序,不以终端来区分
      ps -ax 所有进程
    2. 终止进程
      kill -9 [PID] 9表示立即终止
    3. 运行时间较长的程序,有时需要断开终端之后还要能够自动进行(终端xshell断开后程序默认会停止程序(nohup则会忽略断开的信息,继续执行,&表示加入作业表待调度))
      nohup python path/train_net.py > log.txt 2>&1 &
    4. ls当前路径下所有文件及文件夹
    5. vim的使用 vim myprogram.py
      iinsert(插入编辑代码), esc(退出当前模式), :wq(保存并退出), q!(强制!退出),set nu(显示代码行)
    6. 查看GPU显存使用情况
      nvidia-smi或者watch 'nvidia-smi'
  • conda指令大全参考

  • python

    1. setuptools
      将自己的package(包含有__init__.py的文件夹)安装到python环境中去,
      简单用法如下, 【细节参考】

      from setuptools import setup, find_packages
      setup(name = "package",
      version = "0.1",
      packages = find_packages(),)
      

      之后就可以在python中直接import自己写的module了。

    2. 关于import的相对路径方式和绝对路径方式
      (1) 一个引用了相对路径import(也就是from . import *的形式)的模块,不能直接用普通方式运行(比如直接在IDE里run,或者python my_module.py),会报import越界错误。因为python中直接运行一个模块,它会默认将这个模块所在的当前路径作为最顶层的路径。
      比如,直接运行任何一个module时,

      if __name__ == '__main__':
      	print('__name__ ', __name__) # __main__
      	print('__package__ ', __package__) # None
      

      可以看到,当前的package因为是最顶层的,所以python返回它是None。而相对路径的使用,需要明确当前工作环境是在哪个package下,这样才能用.操作符来在当前package寻找或是..返回上一级package搜索路径。也就是说,package为None条件下,自然无法用相对路径import啦。
      (2) 【总结一下】
      *在一个主modulemain.py(就是要run的module)里边,不使用相对路径;

      *一般如果project比较小,在当前文件夹下只有几个module,应该import modules 或者from modules import *

      *但如果project比较大,包含较多级子package和子module,同样在当前文件夹下应该直接import任意package和module,但是在子package中就一定要用到相对路径的import(包括子子package和子module),,因为对于一个project来说,我们只会在project的根目录下运行计算,工作__package__会是project的根目录,所以在子package中直接import该package下的module时同样会出错(需要相对路径),

      # package/module1.py, module2.py
      # in module1.py:
      from . import module2 # pass
      import module2 # error
      

      *对于含有相对路径的module.py,需要终端运行时,先cd project_root,然后使用命令python -m project_root.package.module注意不要带.py后缀。当然也可以在main.py中直接import module,然后在main.py中调用并测试该module。

      *总而言之,对于大的project来说,package要规范。python的package要有__init__.py文件,根目录使用绝对路径导入,子级使用相对路径导入。
      根目录下.py文件需要使用绝对路径方式来import,比如import module.* as x或者from module import * as x
      子目录下需要相对路径来导入包,比如from .module import * as x

    3. 日志文件logger 【Reference Blog】

      import logging
      import os
      
      if __name__ == '__main__':
      	log_path = './logs'
      	if not os.path.exists(log_path):
      		os.mkdir(log_path)
      	
      	logging.basicConfig(level = logging.INFO,format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
      	logger = logging.getLogger('training logger.')
      	handler = logging.FileHandler(log_path+'/log.txt')
      	formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
      	handler.setFormatter(formatter)
      	logger.addHandler(handler)
      	
      	logger.info("Start print log")
      	logger.debug("Do something")
      	logger.warning("Something maybe fail.")
      	logger.info("Finish")
      	
      	logger.removeHandler(handler)
      

      当然,封装一下会更好…

    4. 怎样写一个关于模型训练的配置文件config
      很喜欢rcnn鼻祖开发的这个yacs配置模块,简单记录下用法,
      (1) 导入from yacs.config import CfgNode as CN
      (2) 相当于个树状结构,由很多个基本的节点CN()组成。首先实例化一个根节点_C = CN(),每添加一个子节点就要实例化新的_C.CHILd = CN(),如果这个子节点后面没有子子节点了,就直接赋值。
      先上代码

      import os
      from yacs.config import CfgNode as CN
      
      def defcfg():
      	# instantiation
      	_C = CN()
      	
      	# NAME
      	_C.NAME = CN()
      	_C.NAME.FIRST_NAME = 'j'
      	_C.NAME.LAST_NAME = 'deepha'
      	
      	# only child node with child_child multi-nodes needs new instantiation
      	_C.AGE = 25
      	
      	# HOBBY
      	_C.HOBBY = CN()
      	_C.HOBBY.GAME = 'WANG ZHE RONG YAO'
      	_C.HOBBY.SPORTS = 'PING PANG'
      	
      	return _C
      
      def cfg2yaml(cfg, root = 'cfgs', path = 'demo_cfg.yaml'):
      	if not os.path.exists(root):
      		os.mkdir(root)
      	with open(os.path.join(root, path), 'w', encoding='utf-8') as f:
      		print(cfg, file=f)
      	print('Done.')
      	
      if __name__ == '__main__':
      	# 保存到'.yaml文件'
      	cfg2yaml(defcfg())
      	# 从'.yaml'把配置汇入更新当前cfg
      	cfg = defcfg()
      	cfg.merge_from_file('new_config.yaml')
      	# 使它不再可变
      	cfg.freeze()
      

      用法,像maskrcnn_benchmark,先定义好初始默认的配置模块config_default.py,之后导入这个模块并且使用merge_from_file()来更新。

    5. 字典dict的注册机制registry简单学习
      *动机
      (1) 有一张完善的注册表,在复杂的任务系统中,会方便管理;
      (2) 通过注册表的关键字,可以方便快捷地索引找到我们需要的内容;
      (3) 唯一性;
      注册表上的ID只能对应一个具体对象,注册表上不存在的ID,自然无法搜索得到;
      (4) 先注册,才存在;

      *在注册的时候,有时候并不知道这个键对应的值是什么,所以无法直接传入这个值args。可能在注册时需要当场确认一些具体情况然后再注册。也就是说,希望在注册时根据具体情况来给入这个(key-value pair)的值。进一步,我在使用注册器register的时候,希望临时得到一个返回值(细节已封装好),然后加入注册表Registry()
      这个时候就可以考虑装饰器了。目标是,当我有一张注册表(实例化后的Registry()),我只需给注册器register(key_name)添加一个当前对象的别名参数,它就自己执行一个任务(function()),获取对象的具体信息并完成注册。
      而python的装饰器decorator的使用,其实就是给(装饰函数输入)一个函数,对这个函数进行一些额外的补充(装饰),让它在执行的时候,多做一些功能外的可能必要的任务。
      一般使用,

      @decorator
      def function():
      	pass
      	# 这就对function函数进行了修饰,之后在执行这个函数时,会自动地加以修饰。
      

      更高级的用法,我们可以把装饰器封装一下实现复杂的修饰(类或复杂点的函数)。有时候修饰功能也需要根据给定的参数来完成修饰,总之,只要@后面的decorator返回的是一个修饰函数,就是一个修饰器。
      实践

      # 假如我要对fn(*args)函数进行装饰,那我首先定义一个装饰函数把它包起来
      def decorate1(fn):
      	# 具体的装饰过程封装在一个函数里边,注意这个函数要提供给fn()必要的形参
      	def _fn(*args):
      		print('decorating...')
      		fn(*args)
      		# 项目代码里在这里 return fn # 实验发现不return fn也是可以的,那就不要了
      	return _fn # 返回装饰后的函数
      # 之后就可以这么用了
      @decorate
      def funcion(*args):
      	...
      	return
      # 也就是每当调用function(),就会自动使用装饰函数。
      

      实际上,很多时候有用到带有参数的装饰,这时候可以再外包一层函数,让它带参执行之后返回一个装饰器也是一样的,更高级的封装到类里边。

      def extra_function(*args1):
      	"""
      	do something
      	"""
      	def decorate(fn):
      		def _fn(*args2):
      			# decorating...
      			# after decorating
      			fn(*args2)
      		return _fn
      	return decorate
      
      # 之后在使用时,必须!要带(),也就是要先执行,否则它返回的是函数本身而不是装饰函数
      @extra_function()
      def funtion(*args):
      	...
      	return
      # 复杂的则类封装实现...
      

      回到注册器,简单学习下maskrcnn_benchmark的模型注册装饰器,

      def _register_generic(rdict, key, value):
      	assert key not in rdict
      	rdict[key] = value
      
      class Registry(dict):
      	def __init__(self):
      		super(Registry, self).__init__()
      
      	def register(self, key, value=None):
      		if value is not None:
          		_register_generic(self, key, value)
          		return
      
      		# decorator
      		def _register(fn):
          			_register_generic(self, key, fn) 
          			# 这里是fn而不是fn(),
          			# 保存生成模型的方法比直接保存模型信息要更简约,耗存也更小
      				# return fn
      		return _register
      
      
      model = Registry()
      
      import numpy as np
      def vgg():
      	return np.random.randn(100, 100)
      
      model.register('vgg', vgg)
      
      @model.register('resnet')
      def build_resnet():
      	resnet = np.random.randn(100, 100)
      	return resnet
      # 这样一来,model字典里就有了`vgg`和`resnet`两个模型的生成方法
      # 调用:model['model_name'](); 因为model字典实际保存的是函数
      
    6. os.mkdir(path)os.makedirs(path)的区别
      os.mkdir()创建路径中的最后一级目录,即:只创建path_03目录,而如果之前的目录不存在并且也需要创建的话,就会报错。os.makedirs()创建多层目录,

      import os  
      
      path_01 = 'Test\\path_01\\path_02\\path_03'  
      try:  
      	os.mkdir(path_01)  
      	print u'第一次创建成功!'  
      except:  
      	print u'第一次创建失败!'  
      	try:  
      		os.makedirs(path_01)  
      		print u'第二次创建成功!'  
       	except:  
      		print u'第二次创建失败!' 
      
    7. namedtuple
      用法参考

      	from collections import namedtuple
      	# 相当于类Person继承自类namedtuple, 同时添加新的成员属性(域);
      	# namedtuple()初始化需要两个参数,第一个是这个继承自namedtuple的新类的type属性值,
      	# 第二个参数是这个namedtuple新类的域名(或者说属性名)集,也就是要添加进来的新成员名;
      	Person = namedtuple('Person', 'name, sex, age, power') 
      	# Person类具有成员name, sex, age, power,,
      	liyun = Person(name='LiYun', age=24, sex='Women', power=10000)
      	# 可以直接.member访问成员属性
      	name = liyun.name
      	# 也可以将namedtuple()化为字典(OrderedDict)输出
      	print(liyun._asdict())
      	# 最后一点:namedtuple也是一种tuple,同样的他也不能够改变值
      
    8. 删除文件和文件夹

      import os
      import shutil
      
      os.remove(path)   #删除文件
      os.removedirs(path)   #删除空文件夹
      
      shutil.rmtree(path)    #递归删除文件夹
      
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值