概述
-
Linux
- 查看服务器上的进程
ps -u
(当前用户的程序)
ps -au
(所有用户的程序)
前面两个够用了
ps -a
服务器上的所有程序
ps -x
所有程序,不以终端来区分
ps -ax
所有进程 - 终止进程
kill -9 [PID]
9表示立即终止 - 运行时间较长的程序,有时需要断开终端之后还要能够自动进行(终端xshell断开后程序默认会停止程序(nohup则会忽略断开的信息,继续执行,&表示加入作业表待调度))
nohup python path/train_net.py > log.txt 2>&1 &
ls
当前路径下所有文件及文件夹- vim的使用
vim myprogram.py
i
insert(插入编辑代码),esc
(退出当前模式),:wq
(保存并退出),q!
(强制!退出),set nu
(显示代码行) - 查看GPU显存使用情况
nvidia-smi
或者watch 'nvidia-smi'
- 查看服务器上的进程
-
conda
指令大全参考 -
python
-
setuptools
将自己的package(包含有__init__.py
的文件夹)安装到python环境中去,
简单用法如下, 【细节参考】from setuptools import setup, find_packages setup(name = "package", version = "0.1", packages = find_packages(),)
之后就可以在python中直接
import
自己写的module了。 -
关于
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
-
日志文件
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)
当然,封装一下会更好…
-
怎样写一个关于模型训练的配置文件
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()
来更新。 -
字典
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字典实际保存的是函数
-
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'第二次创建失败!'
-
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,同样的他也不能够改变值
-
删除文件和文件夹
import os import shutil os.remove(path) #删除文件 os.removedirs(path) #删除空文件夹 shutil.rmtree(path) #递归删除文件夹
-
最后
以上就是超级唇彩为你收集整理的linux指令与python模型训练日志、配置相关问题的全部内容,希望文章能够帮你解决linux指令与python模型训练日志、配置相关问题所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复