记录在日常看到的比较优雅的python代码写法,努力向大佬靠拢。

1. 词序列转化为index序列

要求:
根据词典,将词序列转化为对应的index序列。对于词典中未出现的词,则将其index设置为词典中<UNK>的序号。
代码:
x = [dict.get(t, dict["<UNK>"]) for t in tokens]
解释:
tokens为词序列;变量dict为一个字典;使用 dict.get()方法,执行的操作为假如 t 在词典中,则返回 t 的index,假如不在,则返回 UNK的index。

2. 计算训练一次需要多少个batch

要求:
已知 total_num为训练数据条数,batch_size为一个batch的大小,想计算训练一次(过完全部训练数据)需要多少个batch
代码:
batch_num = total_num // batch_size + int(total_num % batch_size != 0 )
另一种方法:(需要导入math包)

import math
batch_num = math.ceil(total_num / batch_size)

3. 保存一个深度学习模型中的所有Variable信息

要求:
将一个深度学习的模型的全部变量信息保存在一个txt文件中,以方便推荐和理解模型。
代码:

with tf.Session() as sess:

    # logdir为保存模型的文件夹路径,ckpt为从logdir下读取到的最新的模型的地址,假如没读到,则 ckpt为None
    ckpt = tf.train.latest_checkpoint(logdir)  

    # 第一次训练时,初始化所有变量,并保存所有变量的信息
    if ckpt is None:
        logging.info("Initializing from scratch")
        sess.run(tf.global_variables_initializer())
        save_variable_specs(os.path.join(logdir, "specs"))   # 保存模型中变量的信息

其使用的 save_variable_specs()方法如下:

def save_variable_specs(fpath):
    '''Saves information about variables such as
    their name, shape, and total parameter number
    fpath: string. output file path

    Writes
    a text file named fpath.
    '''
    def _get_size(shp):
        '''Gets size of tensor shape
        shp: TensorShape

        Returns
        size
        '''
        size = 1
        for d in range(len(shp)):
            size *=shp[d]
        return size

    params, num_params = [], 0
    for v in tf.global_variables():
        params.append("{}==={}".format(v.name, v.shape))
        num_params += _get_size(v.shape)
    print("num_params: ", num_params)
    with open(fpath, 'w') as fout:
        fout.write("num_params: {}\n".format(num_params))
        fout.write("\n".join(params))
    logging.info("Variables info has been saved.")

这样就可以将变量信息保存到 logdir/specs文件中。如下:

num_params: 54159363
shared_weight_matrix/weight_mat:0===(32000, 256)
encoder/num_blocks_0/multihead_attention/dense/kernel:0===(256, 256)
encoder/num_blocks_0/multihead_attention/dense_1/kernel:0===(256, 256)
encoder/num_blocks_0/multihead_attention/dense_2/kernel:0===(256, 256)
encoder/num_blocks_0/multihead_attention/ln/beta:0===(256,)
encoder/num_blocks_0/multihead_attention/ln/gamma:0===(256,)
encoder/num_blocks_0/positionwise_feedforward/dense/kernel:0===(256, 1024)
encoder/num_blocks_0/positionwise_feedforward/dense/bias:0===(1024,)
encoder/num_blocks_0/positionwise_feedforward/dense_1/kernel:0===(1024, 256)
encoder/num_blocks_0/positionwise_feedforward/dense_1/bias:0===(256,)
encoder/num_blocks_0/positionwise_feedforward/ln/beta:0===(256,)

学习自Github: https://github.com/Kyubyong/transformer

4. 给定一个token_list,初始化一个token-idx dict

vocab = dict(zip(token_list, range(len(token_list))))

5. 给定一个path,创建一个树目录,假如存在则跳过

def maketree(path):
    try:
        os.makedirs(path)
    except:
        pass

6.已知encoder(一个dict: token->idx),得到decoder:

decoder = {v: k for k, v in encoder.items()}

7. tqdm的一些简便用法

from tqdm import tqdm, trange

# 以下两种写法相同,但第二种更加优雅
for i in tqdm(range(5)):
for i in trange(5):

8.使用retry库来实现重试功能

看下面两个例子即可:
① 不使用retry,就需要手动捕捉错误,实现重试:

import time
def do_something():
  xxx
 
for i in range(5):
  try:
    do_something()
    break
  except:
    time.sleep(2)

② 使用了retry之后,直接添加装饰器如下:

from retry import retry
 
@retry(tries=5, delay=2)
def do_something():
    xxx
 
do_something()

此例转载自:

https://blog.csdn.net/u013066730/article/details/82986949

9.获取某个目录下的所有文件路径

def get_all_files_from_dir(dir_path):
    """从某个指定目录下读取所有文件的完整路径
    """
    result = []

    for root, dirs, files in os.walk(dirname):

        for filename in files:
            apath = os.path.join(root, filename)  # 合并成一个完整路径

            # 这里可以对根据ext对文件进行一些过滤和检查
            # ext = os.path.splitext(apath)[1]    # 获取文件后缀 [0]获取的是除了文件名以外的内容

            result.append(apath)

    return result

如上所示,还可以加入一些限制条件,使得只获取到我们想要的文件。

10.自定义日志配置

除了使用logging.basicConfig这个默认配置以外,还可以自定义日志配置,控制日志内容等级和流向等。比如下面这个配置,就可以既向日志文件输出,又可以向控制台输出(好处是方便查看,且二者可以设置不同的日志等级,很灵活)。

def logger_config(
        prefix: str = 'NULL',
        file_level: str = 'INFO',
        console_level: str = 'INFO',
        log_file: str = 'test.log') -> typing.NoReturn:
    """设置日志,既向日志文件打印,又向控制台打印
    :param prefix: 设置日志的前缀,即[]中的内容
    :param file_level: 向日志文件中输出的日志等级
    :param console_level: 向控制台输出的日志等级
    :param log_file: 日志文件路径
    :return: 无返回值
    """
    # 获取一个Logger实例
    logger = logging.getLogger()
    logger.setLevel('NOTSET')    # 设置最低的日志级别,只有高于(包含)这个级别的日志才会被输出

    # 设置日志格式
    BASIC_FORMAT = f'[{prefix}]%(asctime)s - %(levelname)s: %(message)s'
    DATE_FORMAT = '%Y-%m-%d %H:%M:%S'
    formatter = logging.Formatter(BASIC_FORMAT, DATE_FORMAT)

    # 设置输出到控制台的handler
    chlr = logging.StreamHandler()
    chlr.setFormatter(formatter)
    chlr.setLevel(console_level)   # 设置控制台日志级别
    # 设置输出到文件的handler
    fhlr = logging.FileHandler(filename=log_file, encoding='utf-8')    # 注意这里设置日志文件的编码
    fhlr.setFormatter(formatter)
    fhlr.setLevel(file_level)    # 设置日志文件日志级别

    # 添加两个handler到logger中
    logger.addHandler(chlr)
    logger.addHandler(fhlr)

使用示例:(假设在某预处理代码中使用:)

import logging
from prepro_utils import logger_config

logger_config(prefix='prepro', file_level='ERROR', console_level='INFO')
logging.info('A INFO TEST!')
logging.error('A ERROR TEST!')

在上面的例子中,我们设置日志文件的等级是ERROR,而控制台的等级是INFO,所以得到的结果是:
① 控制台中
在这里插入图片描述
② 日志文件test.log中
在这里插入图片描述
这样就能很灵活的写日志啦~

常见的日志级别:
levelNumeric value
critical50
error40
warning30
info20
debug10
notset0

本例部分转载自

https://blog.csdn.net/u010895119/article/details/79470443

11.不打乱顺序地去掉list中的重复元素

方法1——借助sort这个API:

l1 = ['b','c','d','b','c','a','a']
l2 = list(set(l1))
l2.sort(key=l1.index)
return l2

或者

l1 = ['b','c','d','b','c','a','a']
l2 = sorted(set(l1),key=l1.index)
return l2

方法2——手写循环:

l1 = ['b','c','d','b','c','a','a']
l2 = []
[l2.append(i) for i in l1 if not i in l2]
return l2

此例转载自:

https://blog.csdn.net/BabyFish13/article/details/79290434

12. 秒数转化为时分秒

def seconds_to_date(seconds: int):
    m, s = divmod(seconds, 60)
    h, m = divmod(m, 60)
    return "%02d时%02d分%02d秒" % (h, m, s)

13. shell读目录下文件并操作

#!/bin/bash
# 获取文件夹下所有文件
folder="."
softfiles=$(ls $folder)

# 遍历操作
for sfile in ${softfiles}
do
    echo "${sfile}"
done

转载自:https://www.cnblogs.com/zzming/p/12608314.html

未完待续.

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值