我是靠谱客的博主 超级唇彩,最近开发中收集的这篇文章主要介绍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)
      #递归删除文件夹
      

最后

以上就是超级唇彩为你收集整理的linux指令与python模型训练日志、配置相关问题的全部内容,希望文章能够帮你解决linux指令与python模型训练日志、配置相关问题所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(31)

评论列表共有 0 条评论

立即
投稿
返回
顶部