【问题标题】:Simplifying the modification of strings from a dynamic list?简化动态列表中字符串的修改?
【发布时间】:2018-10-06 11:23:17
【问题描述】:

我想将字符串列表从一种格式更改为另一种格式。

可以在此处找到完整列表的示例:https://gist.github.com/ProGamerGov/1d728e7ca4cc52abf398277642e4ee78

我正在尝试做的一些例子:

Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))

收件人:

(2): Conv2d(3 -> 64, 3x3, 1,1, 1,1)

还有这个:

Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))

到这里:

(8): Conv2d(64 -> 128, 3x3, 1,1, 1,1)

我当前的代码设置如下所示:

def modify_text(text, new): 
    return text.replace(", ","*", 1).replace(", ", new, 1)

for i, layer in enumerate(net): 
        if "Conv2d" in str(layer):
           layer = str(layer).replace(","," ->", 1)
           layer = modify_text(layer, "x").replace("kernel_size=(", "").replace("stride=(", "").replace("padding=(", "").replace(")","", 3)
           layer = modify_text(modify_text(layer, ","), ",").replace("*",", ")
           print("  (" + str(i+1) + "): " + layer)

但我觉得我可以有更好看/更简单的方法来做到这一点?

编辑,我已将设置简化为:

regx_map = r'(2d).*?(\d+).*?(\d+).*?(\d+).*?(\d+).*?(\d+).*?(\d+).*?(\d+).*?(\d+).*'
regx_pool = r'(2d).*?(\d+).*?(\d+).*?(\d+).*'
for i, layer in enumerate(net): 
     if "Conv2d" in str(layer):
          print("  (" + str(i+1) + "): " + re.sub(regx_map, r'\1(\2 -> \3, \4x\5, \6,\7, \8,\9)', str(layer)))
     elif "MaxPool2d" in str(layer) or "AvgPool2d" in str(layer):
          print("  (" + str(i+1) + "): " + re.sub(regx_pool, r'\1(\2x\2, \3,\3)', str(layer)))
     else:
          print("  (" + str(i+1) + "): " + "nn." + str(layer).split("(", 1)[0]) 

【问题讨论】:

    标签: python string replace split


    【解决方案1】:

    你可以使用正则表达式来匹配:

    import re
    s = 'Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))'
    regx = r'(Conv2d).*?(\d+).*?(\d+).*?(\d+).*?(\d+).*?(\d+).*?(\d+).*?(\d+).*?(\d+).*'
    
    print(re.sub(regx, r'\1(\2 -> \3, \4x\5, \6,\7,\8,\9)', s))
    

    输出:

    Conv2d(3 -> 64, 3x3, 1,1,1,1)
    

    如果你想让正则表达式稍微健壮一些,但代价是它很长:

    (Conv2d)\((\d+),\s(\d+),\skernel_size=\((\d+),\s(\d+)\),\sstride=\((\d+),\s(\d+)\),\spadding=\((\d+),\s(\d+)\)\)
    

    试试看here

    【讨论】:

    • 感谢您的帮助!例如,我将如何使用正则表达式将 Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) 更改为 64 3 3 3?
    • 我正在尝试将MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False) 放入与上面的 regx 变量相同的设置中,但我无法让它工作。但我猜格式略有不同?
    • 你希望你的输出是什么样的?
    • 我需要它看起来像:MaxPool2d(2x2, 2,2)。此外,根据用户的选择,“MaxPool”字符串将改为:AvgPool2d(kernel_size=2, stride=2, padding=0)。 “AvgPool”字符串需要以与 MaxPool 相同的格式结束:AvgPool2d(2x2, 2,2)。我不确定这两个字符串是否足够相似,可以将它们合并成一个正则表达式。
    • 也许最好的选择可能是定义一个为所有 3 种字符串设置/格式创建映射的单个 regx 变量,然后我可以添加 MaxPool2d、AvgPool2d 或 @987654333 @当我想打印图层名称/字符串时。
    【解决方案2】:

    您可以使用正则表达式解析字符串中函数的签名,将参数转换为所需的语法,然后再使用re.sub添加新的签名:

    import re
    import itertools
    def signature(header):
      s = re.findall('(?<=\()[\w\W]+(?=\)$)', header)
      return re.split(',\s(?=\w\w)', s[0]) if s else ''
    
    def combine_args(d):
       if '=' in d:
          return '{}x{}'.format(*re.findall('\d+', d)) if 'kernel_size' in d and len(re.findall('\d+', d)) == 2 else '{},{}'.format(*re.findall('\d+', d)) if len(re.findall('\d+', d)) == 2 else d
       return d
    
    def combine_header(d):
      vals = [[a, list(b)] for a, b in itertools.groupby(d, key=lambda x:x.isdigit())]
      return list(itertools.chain(*[[' -> '.join(b)] if a else [combine_args(i) for i in b] for a, b in vals]))
    
    lines = ['TVLoss()', 'Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))', 'ReLU(inplace)', 'StyleLoss((gram): GramMatrix()(crit): MSELoss())', 'Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))', 'ReLU(inplace)', 'MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)', 'Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))', 'ReLU(inplace)', 'StyleLoss((gram): GramMatrix()(crit): MSELoss())', 'Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))', 'ReLU(inplace)', 'MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)', 'Conv2d(128, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))', 'ReLU(inplace)', 'StyleLoss((gram): GramMatrix()(crit): MSELoss())', 'Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))', 'ReLU(inplace)', 'Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))', 'ReLU(inplace)', 'Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))', 'ReLU(inplace)', 'MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)', 'Conv2d(256, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))', 'ReLU(inplace)', 'StyleLoss((gram): GramMatrix()(crit): MSELoss())', 'Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))', 'ReLU(inplace)', 'ContentLoss((crit): MSELoss())', 'Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))', 'ReLU(inplace)', 'Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))', 'ReLU(inplace)', 'MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)', 'Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))', 'ReLU(inplace)', 'StyleLoss((gram): GramMatrix()(crit): MSELoss())']
    final_lines = [re.sub('(?<=\()[\w\W]+(?=\)$)', ', '.join(combine_header(c)), a) for a, c in zip(lines, map(signature, lines))]
    

    输出:

    ['TVLoss()', 'Conv2d(3 -> 64, 3x3, 1,1, 1,1)', 'ReLU(inplace)', 'StyleLoss((gram): GramMatrix()(crit): MSELoss())', 'Conv2d(64 -> 64, 3x3, 1,1, 1,1)', 'ReLU(inplace)', 'MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)', 'Conv2d(64 -> 128, 3x3, 1,1, 1,1)', 'ReLU(inplace)', 'StyleLoss((gram): GramMatrix()(crit): MSELoss())', 'Conv2d(128 -> 128, 3x3, 1,1, 1,1)', 'ReLU(inplace)', 'MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)', 'Conv2d(128 -> 256, 3x3, 1,1, 1,1)', 'ReLU(inplace)', 'StyleLoss((gram): GramMatrix()(crit): MSELoss())', 'Conv2d(256 -> 256, 3x3, 1,1, 1,1)', 'ReLU(inplace)', 'Conv2d(256 -> 256, 3x3, 1,1, 1,1)', 'ReLU(inplace)', 'Conv2d(256 -> 256, 3x3, 1,1, 1,1)', 'ReLU(inplace)', 'MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)', 'Conv2d(256 -> 512, 3x3, 1,1, 1,1)', 'ReLU(inplace)', 'StyleLoss((gram): GramMatrix()(crit): MSELoss())', 'Conv2d(512 -> 512, 3x3, 1,1, 1,1)', 'ReLU(inplace)', 'ContentLoss((crit): MSELoss())', 'Conv2d(512 -> 512, 3x3, 1,1, 1,1)', 'ReLU(inplace)', 'Conv2d(512 -> 512, 3x3, 1,1, 1,1)', 'ReLU(inplace)', 'MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)', 'Conv2d(512 -> 512, 3x3, 1,1, 1,1)', 'ReLU(inplace)', 'StyleLoss((gram): GramMatrix()(crit): MSELoss())']
    

    【讨论】:

      猜你喜欢
      • 2012-11-11
      • 1970-01-01
      • 1970-01-01
      • 2022-01-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多